packages feed

hermit 0.2.0.0 → 0.3.0.0

raw patch · 126 files changed

+14182/−11254 lines, 126 filesdep +temporarydep +terminfodep ~kuredep ~processPVP ok

version bump matches the API change (PVP)

Dependencies added: temporary, terminfo

Dependency ranges changed: kure, process

API changes (from Hackage documentation)

- Language.HERMIT.Context: CASEALT :: HermitBindingSite
- Language.HERMIT.Context: CASEWILD :: CoreExpr -> (AltCon, [Var]) -> HermitBindingSite
- Language.HERMIT.Context: FORALL :: HermitBindingSite
- Language.HERMIT.Context: LAM :: HermitBindingSite
- Language.HERMIT.Context: NONREC :: CoreExpr -> HermitBindingSite
- Language.HERMIT.Context: REC :: CoreExpr -> HermitBindingSite
- Language.HERMIT.Context: addAltBindings :: AddBindings c => [Var] -> c -> c
- Language.HERMIT.Context: addBindingGroup :: AddBindings c => CoreBind -> c -> c
- Language.HERMIT.Context: addCaseWildBinding :: AddBindings c => (Id, CoreExpr, CoreAlt) -> c -> c
- Language.HERMIT.Context: addForallBinding :: AddBindings c => TyVar -> c -> c
- Language.HERMIT.Context: addHermitBindings :: AddBindings c => [(Var, HermitBindingSite)] -> c -> c
- Language.HERMIT.Context: addLambdaBinding :: AddBindings c => Var -> c -> c
- Language.HERMIT.Context: boundIn :: ReadBindings c => Var -> c -> Bool
- Language.HERMIT.Context: boundVars :: BoundVars c => c -> Set Var
- Language.HERMIT.Context: class AddBindings c
- Language.HERMIT.Context: class BoundVars c
- Language.HERMIT.Context: class HasCoreRules c
- Language.HERMIT.Context: class HasGlobalRdrEnv c
- Language.HERMIT.Context: class BoundVars c => ReadBindings c
- Language.HERMIT.Context: data HermitBindingSite
- Language.HERMIT.Context: data HermitC
- Language.HERMIT.Context: findBoundVars :: BoundVars c => Name -> c -> [Var]
- Language.HERMIT.Context: hermitBindingExpr :: HermitBinding -> Maybe CoreExpr
- Language.HERMIT.Context: hermitBindingSiteExpr :: HermitBindingSite -> Maybe CoreExpr
- Language.HERMIT.Context: hermitBindings :: ReadBindings c => c -> Map Var HermitBinding
- Language.HERMIT.Context: hermitCoreRules :: HasCoreRules c => c -> [CoreRule]
- Language.HERMIT.Context: hermitDepth :: ReadBindings c => c -> BindingDepth
- Language.HERMIT.Context: hermitGlobalRdrEnv :: HasGlobalRdrEnv c => c -> GlobalRdrEnv
- Language.HERMIT.Context: initHermitC :: ModGuts -> HermitC
- Language.HERMIT.Context: instance AddBindings (SnocPath crumb)
- Language.HERMIT.Context: instance AddBindings HermitC
- Language.HERMIT.Context: instance BoundVars HermitC
- Language.HERMIT.Context: instance ExtendPath HermitC Crumb
- Language.HERMIT.Context: instance HasCoreRules HermitC
- Language.HERMIT.Context: instance HasGlobalRdrEnv HermitC
- Language.HERMIT.Context: instance ReadBindings HermitC
- Language.HERMIT.Context: instance ReadPath HermitC Crumb
- Language.HERMIT.Context: lookupHermitBinding :: ReadBindings c => Var -> c -> Maybe HermitBinding
- Language.HERMIT.Context: type BindingDepth = Int
- Language.HERMIT.Context: type HermitBinding = (BindingDepth, HermitBindingSite)
- Language.HERMIT.Core: Alt_Con :: Crumb
- Language.HERMIT.Core: Alt_RHS :: Crumb
- Language.HERMIT.Core: Alt_Var :: Int -> Crumb
- Language.HERMIT.Core: AppCo_Arg :: Crumb
- Language.HERMIT.Core: AppCo_Fun :: Crumb
- Language.HERMIT.Core: AppTy_Arg :: Crumb
- Language.HERMIT.Core: AppTy_Fun :: Crumb
- Language.HERMIT.Core: App_Arg :: Crumb
- Language.HERMIT.Core: App_Fun :: Crumb
- Language.HERMIT.Core: AxiomInstCo_Arg :: Int -> Crumb
- Language.HERMIT.Core: AxiomInstCo_Axiom :: Crumb
- Language.HERMIT.Core: AxiomInstCo_Index :: Crumb
- Language.HERMIT.Core: Case_Alt :: Int -> Crumb
- Language.HERMIT.Core: Case_Binder :: Crumb
- Language.HERMIT.Core: Case_Scrutinee :: Crumb
- Language.HERMIT.Core: Case_Type :: Crumb
- Language.HERMIT.Core: Cast_Co :: Crumb
- Language.HERMIT.Core: Cast_Expr :: Crumb
- Language.HERMIT.Core: CoVarCo_CoVar :: Crumb
- Language.HERMIT.Core: Co_Co :: Crumb
- Language.HERMIT.Core: Def :: Id -> CoreExpr -> CoreDef
- Language.HERMIT.Core: Def_Id :: Crumb
- Language.HERMIT.Core: Def_RHS :: Crumb
- Language.HERMIT.Core: ForAllCo_Body :: Crumb
- Language.HERMIT.Core: ForAllCo_TyVar :: Crumb
- Language.HERMIT.Core: ForAllTy_Body :: Crumb
- Language.HERMIT.Core: ForAllTy_Var :: Crumb
- Language.HERMIT.Core: FunTy_CoDom :: Crumb
- Language.HERMIT.Core: FunTy_Dom :: Crumb
- Language.HERMIT.Core: InstCo_Co :: Crumb
- Language.HERMIT.Core: InstCo_Type :: Crumb
- Language.HERMIT.Core: LRCo_Co :: Crumb
- Language.HERMIT.Core: LRCo_LR :: Crumb
- Language.HERMIT.Core: Lam_Body :: Crumb
- Language.HERMIT.Core: Lam_Var :: Crumb
- Language.HERMIT.Core: Let_Bind :: Crumb
- Language.HERMIT.Core: Let_Body :: Crumb
- Language.HERMIT.Core: LitTy_TyLit :: Crumb
- Language.HERMIT.Core: Lit_Lit :: Crumb
- Language.HERMIT.Core: ModGuts_Prog :: Crumb
- Language.HERMIT.Core: NonRec_RHS :: Crumb
- Language.HERMIT.Core: NonRec_Var :: Crumb
- Language.HERMIT.Core: NthCo_Co :: Crumb
- Language.HERMIT.Core: NthCo_Int :: Crumb
- Language.HERMIT.Core: ProgCons :: CoreBind -> CoreProg -> CoreProg
- Language.HERMIT.Core: ProgCons_Head :: Crumb
- Language.HERMIT.Core: ProgCons_Tail :: Crumb
- Language.HERMIT.Core: ProgNil :: CoreProg
- Language.HERMIT.Core: Rec_Def :: Int -> Crumb
- Language.HERMIT.Core: Refl_Type :: Crumb
- Language.HERMIT.Core: SymCo_Co :: Crumb
- Language.HERMIT.Core: Tick_Expr :: Crumb
- Language.HERMIT.Core: Tick_Tick :: Crumb
- Language.HERMIT.Core: TransCo_Left :: Crumb
- Language.HERMIT.Core: TransCo_Right :: Crumb
- Language.HERMIT.Core: TyConAppCo_Arg :: Int -> Crumb
- Language.HERMIT.Core: TyConAppCo_TyCon :: Crumb
- Language.HERMIT.Core: TyConApp_Arg :: Int -> Crumb
- Language.HERMIT.Core: TyConApp_TyCon :: Crumb
- Language.HERMIT.Core: TyVarTy_TyVar :: Crumb
- Language.HERMIT.Core: Type_Type :: Crumb
- Language.HERMIT.Core: UnsafeCo_Left :: Crumb
- Language.HERMIT.Core: UnsafeCo_Right :: Crumb
- Language.HERMIT.Core: Var_Id :: Crumb
- Language.HERMIT.Core: appCount :: CoreExpr -> Int
- Language.HERMIT.Core: bindToIdExprs :: CoreBind -> [(Id, CoreExpr)]
- Language.HERMIT.Core: bindsToProg :: [CoreBind] -> CoreProg
- Language.HERMIT.Core: data CoreDef
- Language.HERMIT.Core: data CoreProg
- Language.HERMIT.Core: data Crumb
- Language.HERMIT.Core: defToIdExpr :: CoreDef -> (Id, CoreExpr)
- Language.HERMIT.Core: defsToRecBind :: [CoreDef] -> CoreBind
- Language.HERMIT.Core: deprecatedLeftSibling :: Crumb -> Maybe Crumb
- Language.HERMIT.Core: deprecatedRightSibling :: Crumb -> Maybe Crumb
- Language.HERMIT.Core: endoFunType :: Monad m => CoreExpr -> m Type
- Language.HERMIT.Core: exprTypeOrKind :: CoreExpr -> Type
- Language.HERMIT.Core: funArgResTypes :: Monad m => CoreExpr -> m (Type, Type)
- Language.HERMIT.Core: funsWithInverseTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type, Type)
- Language.HERMIT.Core: instance Eq Crumb
- Language.HERMIT.Core: instance Read Crumb
- Language.HERMIT.Core: instance Show Crumb
- Language.HERMIT.Core: isCoArg :: CoreExpr -> Bool
- Language.HERMIT.Core: progToBinds :: CoreProg -> [CoreBind]
- Language.HERMIT.Core: showCrumbs :: [Crumb] -> String
- Language.HERMIT.Core: type CoreTickish = Tickish Id
- Language.HERMIT.Dictionary: bashDebugR :: Bool -> [External] -> RewriteH Core
- Language.HERMIT.Dictionary: bashR :: [External] -> RewriteH Core
- Language.HERMIT.Dictionary: externals :: [External]
- Language.HERMIT.Dictionary: mkDict :: [External] -> Dictionary
- Language.HERMIT.Dictionary: pp_dictionary :: Map String (PrettyOptions -> PrettyH CoreTC)
- Language.HERMIT.Dictionary: type Dictionary = Map String [Dynamic]
- Language.HERMIT.External: (.&) :: (Tag a, Tag b) => a -> b -> TagE
- Language.HERMIT.External: (.+) :: Tag a => External -> a -> External
- Language.HERMIT.External: (.||) :: (Tag a, Tag b) => a -> b -> TagE
- Language.HERMIT.External: Bash :: CmdTag
- Language.HERMIT.External: BiRewriteCoreBox :: (BiRewriteH Core) -> BiRewriteCoreBox
- Language.HERMIT.External: Commute :: CmdTag
- Language.HERMIT.External: Context :: CmdTag
- Language.HERMIT.External: CoreBox :: CoreString -> CoreBox
- Language.HERMIT.External: CoreString :: String -> CoreString
- Language.HERMIT.External: CrumbBox :: Crumb -> CrumbBox
- Language.HERMIT.External: Debug :: CmdTag
- Language.HERMIT.External: Deep :: CmdTag
- Language.HERMIT.External: Deprecated :: CmdTag
- Language.HERMIT.External: Eval :: CmdTag
- Language.HERMIT.External: Experiment :: CmdTag
- Language.HERMIT.External: IntBox :: Int -> IntBox
- Language.HERMIT.External: Introduce :: CmdTag
- Language.HERMIT.External: KURE :: CmdTag
- Language.HERMIT.External: Loop :: CmdTag
- Language.HERMIT.External: NameBox :: (Name) -> NameBox
- Language.HERMIT.External: NameListBox :: [Name] -> NameListBox
- Language.HERMIT.External: Navigation :: CmdTag
- Language.HERMIT.External: PathBox :: PathH -> PathBox
- Language.HERMIT.External: PreCondition :: CmdTag
- Language.HERMIT.External: Predicate :: CmdTag
- Language.HERMIT.External: Query :: CmdTag
- Language.HERMIT.External: RewriteCoreBox :: (RewriteH Core) -> RewriteCoreBox
- Language.HERMIT.External: RewriteCoreTCBox :: (RewriteH CoreTC) -> RewriteCoreTCBox
- Language.HERMIT.External: Shallow :: CmdTag
- Language.HERMIT.External: Shell :: CmdTag
- Language.HERMIT.External: StringBox :: String -> StringBox
- Language.HERMIT.External: StringListBox :: [String] -> StringListBox
- Language.HERMIT.External: TODO :: CmdTag
- Language.HERMIT.External: TagBox :: TagE -> TagBox
- Language.HERMIT.External: TranslateCoreCheckBox :: (TranslateH Core ()) -> TranslateCoreCheckBox
- Language.HERMIT.External: TranslateCorePathBox :: (TranslateH Core PathH) -> TranslateCorePathBox
- Language.HERMIT.External: TranslateCoreStringBox :: (TranslateH Core String) -> TranslateCoreStringBox
- Language.HERMIT.External: TranslateCoreTCStringBox :: (TranslateH CoreTC String) -> TranslateCoreTCStringBox
- Language.HERMIT.External: Unsafe :: CmdTag
- Language.HERMIT.External: VersionControl :: CmdTag
- Language.HERMIT.External: box :: Extern a => a -> Box a
- Language.HERMIT.External: class Typeable (Box a) => Extern a where type family Box a
- Language.HERMIT.External: class Tag a
- Language.HERMIT.External: data BiRewriteCoreBox
- Language.HERMIT.External: data CmdTag
- Language.HERMIT.External: data CoreBox
- Language.HERMIT.External: data CrumbBox
- Language.HERMIT.External: data External
- Language.HERMIT.External: data IntBox
- Language.HERMIT.External: data NameBox
- Language.HERMIT.External: data NameListBox
- Language.HERMIT.External: data PathBox
- Language.HERMIT.External: data RewriteCoreBox
- Language.HERMIT.External: data RewriteCoreTCBox
- Language.HERMIT.External: data StringBox
- Language.HERMIT.External: data StringListBox
- Language.HERMIT.External: data TagBox
- Language.HERMIT.External: data TagE :: *
- Language.HERMIT.External: data TranslateCoreCheckBox
- Language.HERMIT.External: data TranslateCorePathBox
- Language.HERMIT.External: data TranslateCoreStringBox
- Language.HERMIT.External: data TranslateCoreTCStringBox
- Language.HERMIT.External: dictionaryOfTags :: [(CmdTag, String)]
- Language.HERMIT.External: externFun :: External -> Dynamic
- Language.HERMIT.External: externHelp :: External -> ExternalHelp
- Language.HERMIT.External: externName :: External -> ExternalName
- Language.HERMIT.External: externTags :: External -> [CmdTag]
- Language.HERMIT.External: external :: Extern a => ExternalName -> a -> ExternalHelp -> External
- Language.HERMIT.External: instance (Extern a, Extern b) => Extern (a -> b)
- Language.HERMIT.External: instance Bounded CmdTag
- Language.HERMIT.External: instance Enum CmdTag
- Language.HERMIT.External: instance Eq CmdTag
- Language.HERMIT.External: instance Extern (BiRewriteH Core)
- Language.HERMIT.External: instance Extern (RewriteH Core)
- Language.HERMIT.External: instance Extern (RewriteH CoreTC)
- Language.HERMIT.External: instance Extern (TranslateH Core ())
- Language.HERMIT.External: instance Extern (TranslateH Core PathH)
- Language.HERMIT.External: instance Extern (TranslateH Core String)
- Language.HERMIT.External: instance Extern (TranslateH CoreTC String)
- Language.HERMIT.External: instance Extern CoreString
- Language.HERMIT.External: instance Extern Crumb
- Language.HERMIT.External: instance Extern Int
- Language.HERMIT.External: instance Extern Name
- Language.HERMIT.External: instance Extern PathH
- Language.HERMIT.External: instance Extern String
- Language.HERMIT.External: instance Extern TagE
- Language.HERMIT.External: instance Extern [Name]
- Language.HERMIT.External: instance Extern [String]
- Language.HERMIT.External: instance Read CmdTag
- Language.HERMIT.External: instance Show CmdTag
- Language.HERMIT.External: instance Tag CmdTag
- Language.HERMIT.External: instance Tag TagE
- Language.HERMIT.External: instance Typeable BiRewriteCoreBox
- Language.HERMIT.External: instance Typeable CoreBox
- Language.HERMIT.External: instance Typeable CrumbBox
- Language.HERMIT.External: instance Typeable IntBox
- Language.HERMIT.External: instance Typeable NameBox
- Language.HERMIT.External: instance Typeable NameListBox
- Language.HERMIT.External: instance Typeable PathBox
- Language.HERMIT.External: instance Typeable RewriteCoreBox
- Language.HERMIT.External: instance Typeable RewriteCoreTCBox
- Language.HERMIT.External: instance Typeable StringBox
- Language.HERMIT.External: instance Typeable StringListBox
- Language.HERMIT.External: instance Typeable TagBox
- Language.HERMIT.External: instance Typeable TranslateCoreCheckBox
- Language.HERMIT.External: instance Typeable TranslateCorePathBox
- Language.HERMIT.External: instance Typeable TranslateCoreStringBox
- Language.HERMIT.External: instance Typeable TranslateCoreTCStringBox
- Language.HERMIT.External: matchingExternals :: (Extern tr, Tag t) => t -> [External] -> [(External, tr)]
- Language.HERMIT.External: newtype CoreString
- Language.HERMIT.External: notT :: Tag a => a -> TagE
- Language.HERMIT.External: remTag :: Tag a => a -> External -> External
- Language.HERMIT.External: tagMatch :: Tag a => a -> External -> Bool
- Language.HERMIT.External: toDictionary :: [External] -> Map ExternalName [Dynamic]
- Language.HERMIT.External: toHelp :: [External] -> Map ExternalName ExternalHelp
- Language.HERMIT.External: type ExternalHelp = [String]
- Language.HERMIT.External: type ExternalName = String
- Language.HERMIT.External: unCoreString :: CoreString -> String
- Language.HERMIT.External: unbox :: Extern a => Box a -> a
- Language.HERMIT.GHC: AppTy :: Type -> Type -> Type
- Language.HERMIT.GHC: ForAllTy :: Var -> Type -> Type
- Language.HERMIT.GHC: FunTy :: Type -> Type -> Type
- Language.HERMIT.GHC: LitTy :: TyLit -> Type
- Language.HERMIT.GHC: NumTyLit :: Integer -> TyLit
- Language.HERMIT.GHC: ProgramError :: String -> GhcException
- Language.HERMIT.GHC: StrTyLit :: FastString -> TyLit
- Language.HERMIT.GHC: TyConApp :: TyCon -> [KindOrType] -> Type
- Language.HERMIT.GHC: TyVarTy :: Var -> Type
- Language.HERMIT.GHC: alphaTyVars :: [TyVar]
- Language.HERMIT.GHC: cmpString2Name :: String -> Name -> Bool
- Language.HERMIT.GHC: cmpString2Var :: String -> Var -> Bool
- Language.HERMIT.GHC: cmpTHName2Name :: Name -> Name -> Bool
- Language.HERMIT.GHC: cmpTHName2Var :: Name -> Var -> Bool
- Language.HERMIT.GHC: coAxiomName :: CoAxiom -> Name
- Language.HERMIT.GHC: data GhcException :: *
- Language.HERMIT.GHC: data TyLit :: *
- Language.HERMIT.GHC: data Type :: *
- Language.HERMIT.GHC: exprArity :: CoreExpr -> Arity
- Language.HERMIT.GHC: findNamesFromString :: GlobalRdrEnv -> String -> [Name]
- Language.HERMIT.GHC: findNamesFromTH :: GlobalRdrEnv -> Name -> [Name]
- Language.HERMIT.GHC: fqName :: Name -> String
- Language.HERMIT.GHC: name2THName :: Name -> Name
- Language.HERMIT.GHC: ppIdInfo :: Id -> IdInfo -> SDoc
- Language.HERMIT.GHC: thRdrNameGuesses :: Name -> [RdrName]
- Language.HERMIT.GHC: throwGhcException :: GhcException -> a
- Language.HERMIT.GHC: uqName :: Name -> String
- Language.HERMIT.GHC: var2String :: Var -> String
- Language.HERMIT.GHC: var2THName :: Var -> Name
- Language.HERMIT.Interp: data Interp :: * -> *
- Language.HERMIT.Interp: instance Functor Interp
- Language.HERMIT.Interp: interp :: Typeable a => (a -> b) -> Interp b
- Language.HERMIT.Interp: interpExprH :: Map String [Dynamic] -> [Interp a] -> ExprH -> Either String a
- Language.HERMIT.Kernel: abortK :: Kernel -> IO ()
- Language.HERMIT.Kernel: applyK :: Kernel -> AST -> RewriteH ModGuts -> HermitMEnv -> IO (KureM AST)
- Language.HERMIT.Kernel: data AST
- Language.HERMIT.Kernel: data Kernel
- Language.HERMIT.Kernel: deleteK :: Kernel -> AST -> IO ()
- Language.HERMIT.Kernel: hermitKernel :: (Kernel -> AST -> IO ()) -> ModGuts -> CoreM ModGuts
- Language.HERMIT.Kernel: instance Eq AST
- Language.HERMIT.Kernel: instance Ord AST
- Language.HERMIT.Kernel: instance Show AST
- Language.HERMIT.Kernel: listK :: Kernel -> IO [AST]
- Language.HERMIT.Kernel: queryK :: Kernel -> forall a. AST -> TranslateH ModGuts a -> HermitMEnv -> IO (KureM a)
- Language.HERMIT.Kernel: resumeK :: Kernel -> AST -> IO ()
- Language.HERMIT.Kernel.Scoped: L :: Direction
- Language.HERMIT.Kernel.Scoped: R :: Direction
- Language.HERMIT.Kernel.Scoped: SAST :: Int -> SAST
- Language.HERMIT.Kernel.Scoped: ScopedKernel :: (SAST -> IO (KureM ())) -> IO () -> (forall g. (Injection ModGuts g, Walker HermitC g) => SAST -> RewriteH g -> HermitMEnv -> IO (KureM SAST)) -> (forall a g. (Injection ModGuts g, Walker HermitC g) => SAST -> TranslateH g a -> HermitMEnv -> IO (KureM a)) -> (SAST -> IO (KureM ())) -> IO [SAST] -> (SAST -> IO (KureM [PathH])) -> (SAST -> (LocalPathH -> LocalPathH) -> HermitMEnv -> IO (KureM SAST)) -> (SAST -> IO (KureM SAST)) -> (SAST -> IO (KureM SAST)) -> Kernel -> (SAST -> IO (KureM AST)) -> ScopedKernel
- Language.HERMIT.Kernel.Scoped: T :: Direction
- Language.HERMIT.Kernel.Scoped: U :: Direction
- Language.HERMIT.Kernel.Scoped: abortS :: ScopedKernel -> IO ()
- Language.HERMIT.Kernel.Scoped: applyS :: ScopedKernel -> forall g. (Injection ModGuts g, Walker HermitC g) => SAST -> RewriteH g -> HermitMEnv -> IO (KureM SAST)
- Language.HERMIT.Kernel.Scoped: beginScopeS :: ScopedKernel -> SAST -> IO (KureM SAST)
- Language.HERMIT.Kernel.Scoped: data Direction
- Language.HERMIT.Kernel.Scoped: data ScopedKernel
- Language.HERMIT.Kernel.Scoped: deleteS :: ScopedKernel -> SAST -> IO (KureM ())
- Language.HERMIT.Kernel.Scoped: endScopeS :: ScopedKernel -> SAST -> IO (KureM SAST)
- Language.HERMIT.Kernel.Scoped: extendLocalPath :: Path crumb -> LocalPath crumb -> LocalPath crumb
- Language.HERMIT.Kernel.Scoped: instance Eq Direction
- Language.HERMIT.Kernel.Scoped: instance Eq SAST
- Language.HERMIT.Kernel.Scoped: instance Ord SAST
- Language.HERMIT.Kernel.Scoped: instance Show Direction
- Language.HERMIT.Kernel.Scoped: instance Show SAST
- Language.HERMIT.Kernel.Scoped: kernelS :: ScopedKernel -> Kernel
- Language.HERMIT.Kernel.Scoped: listS :: ScopedKernel -> IO [SAST]
- Language.HERMIT.Kernel.Scoped: modPathS :: ScopedKernel -> SAST -> (LocalPathH -> LocalPathH) -> HermitMEnv -> IO (KureM SAST)
- Language.HERMIT.Kernel.Scoped: moveLocally :: Direction -> LocalPathH -> LocalPathH
- Language.HERMIT.Kernel.Scoped: newtype SAST
- Language.HERMIT.Kernel.Scoped: pathS :: ScopedKernel -> SAST -> IO (KureM [PathH])
- Language.HERMIT.Kernel.Scoped: queryS :: ScopedKernel -> forall a g. (Injection ModGuts g, Walker HermitC g) => SAST -> TranslateH g a -> HermitMEnv -> IO (KureM a)
- Language.HERMIT.Kernel.Scoped: resumeS :: ScopedKernel -> SAST -> IO (KureM ())
- Language.HERMIT.Kernel.Scoped: scopedKernel :: (ScopedKernel -> SAST -> IO ()) -> ModGuts -> CoreM ModGuts
- Language.HERMIT.Kernel.Scoped: toASTS :: ScopedKernel -> SAST -> IO (KureM AST)
- Language.HERMIT.Kernel.Scoped: type LocalPath = SnocPath
- Language.HERMIT.Kure: altAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt
- Language.HERMIT.Kure: altAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt
- Language.HERMIT.Kure: altOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt
- Language.HERMIT.Kure: altT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m AltCon a1 -> (Int -> Translate c m Var a2) -> Translate c m CoreExpr a3 -> (a1 -> [a2] -> a3 -> b) -> Translate c m CoreAlt b
- Language.HERMIT.Kure: appAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: appAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: appCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: appCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: appCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: appCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: appOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: appT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: appTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: appTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: appTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: appTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b
- Language.HERMIT.Kure: axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
- Language.HERMIT.Kure: axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
- Language.HERMIT.Kure: axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
- Language.HERMIT.Kure: axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoAxiom a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: caseAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> Rewrite c m CoreAlt) -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: caseAltAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> (Rewrite c m AltCon, Int -> Rewrite c m Var, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: caseAltAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> (Rewrite c m AltCon, Int -> Rewrite c m Var, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: caseAltOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> (Rewrite c m AltCon, Int -> Rewrite c m Var, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: caseAltT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr sc -> Translate c m Id w -> Translate c m Type ty -> (Int -> (Translate c m AltCon con, Int -> Translate c m Var v, Translate c m CoreExpr rhs)) -> (sc -> w -> ty -> [(con, [v], rhs)] -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: caseAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> Rewrite c m CoreAlt) -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: caseOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> Rewrite c m CoreAlt) -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: caseT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr e -> Translate c m Id w -> Translate c m Type ty -> (Int -> Translate c m CoreAlt alt) -> (e -> w -> ty -> [alt] -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: castAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: castAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: castOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: castT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: coVarCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoVar -> Rewrite c m Coercion
- Language.HERMIT.Kure: coVarCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoVar b -> Translate c m Coercion b
- Language.HERMIT.Kure: coercionR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: coercionT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m CoreExpr b
- Language.HERMIT.Kure: consNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreProg a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreProg b
- Language.HERMIT.Kure: consRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreProg a3 -> ([(a1, a2)] -> a3 -> b) -> Translate c m CoreProg b
- Language.HERMIT.Kure: consRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: consRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreProg a2 -> ([a1] -> a2 -> b) -> Translate c m CoreProg b
- Language.HERMIT.Kure: defAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef
- Language.HERMIT.Kure: defAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef
- Language.HERMIT.Kure: defOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef
- Language.HERMIT.Kure: defT :: (ExtendPath c Crumb, Monad m) => Translate c m Id a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreDef b
- Language.HERMIT.Kure: deprecatedIntToCrumbT :: Monad m => Int -> Translate c m Core Crumb
- Language.HERMIT.Kure: deprecatedIntToPathT :: Monad m => Int -> Translate c m Core PathH
- Language.HERMIT.Kure: forAllCoAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: forAllCoAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: forAllCoOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: forAllCoT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m TyVar a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: forAllTyAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: forAllTyAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: forAllTyOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: forAllTyT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b
- Language.HERMIT.Kure: funTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: funTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: funTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
- Language.HERMIT.Kure: funTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b
- Language.HERMIT.Kure: instCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: instCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: instCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: instCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c Coercion
- Language.HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c Core
- Language.HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c CoreTC
- Language.HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c TyCo
- Language.HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c Type
- Language.HERMIT.Kure: lamAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: lamAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: lamOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: lamT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: letAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreExpr a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: letOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreExpr a3 -> ([(a1, a2)] -> a3 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: letRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: letRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreExpr a2 -> ([a1] -> a2 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: letT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: litR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Literal -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: litT :: (ExtendPath c Crumb, Monad m) => Translate c m Literal b -> Translate c m CoreExpr b
- Language.HERMIT.Kure: litTyR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyLit -> Rewrite c m Type
- Language.HERMIT.Kure: litTyT :: (ExtendPath c Crumb, Monad m) => Translate c m TyLit b -> Translate c m Type b
- Language.HERMIT.Kure: modGutsR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreProg -> Rewrite c m ModGuts
- Language.HERMIT.Kure: modGutsT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreProg a -> (ModGuts -> a -> b) -> Translate c m ModGuts b
- Language.HERMIT.Kure: nonRecAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind
- Language.HERMIT.Kure: nonRecAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind
- Language.HERMIT.Kure: nonRecOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind
- Language.HERMIT.Kure: nonRecT :: (ExtendPath c Crumb, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreBind b
- Language.HERMIT.Kure: nthCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: nthCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: nthCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: nthCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Int a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: progConsAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: progConsAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: progConsOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg
- Language.HERMIT.Kure: progConsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreProg a2 -> (a1 -> a2 -> b) -> Translate c m CoreProg b
- Language.HERMIT.Kure: progNilT :: Monad m => b -> Translate c m CoreProg b
- Language.HERMIT.Kure: promoteAltR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreAlt -> Rewrite c m Core
- Language.HERMIT.Kure: promoteAltT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreAlt b -> Translate c m Core b
- Language.HERMIT.Kure: promoteBindR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreBind -> Rewrite c m Core
- Language.HERMIT.Kure: promoteBindT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreBind b -> Translate c m Core b
- Language.HERMIT.Kure: promoteDefR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreDef -> Rewrite c m Core
- Language.HERMIT.Kure: promoteDefT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreDef b -> Translate c m Core b
- Language.HERMIT.Kure: promoteExprBiR :: (ExtendPath c Crumb, Monad m) => BiRewrite c m CoreExpr -> BiRewrite c m Core
- Language.HERMIT.Kure: promoteExprR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Core
- Language.HERMIT.Kure: promoteExprT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr b -> Translate c m Core b
- Language.HERMIT.Kure: promoteModGutsR :: (ExtendPath c Crumb, Monad m) => Rewrite c m ModGuts -> Rewrite c m Core
- Language.HERMIT.Kure: promoteModGutsT :: (ExtendPath c Crumb, Monad m) => Translate c m ModGuts b -> Translate c m Core b
- Language.HERMIT.Kure: promoteProgR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreProg -> Rewrite c m Core
- Language.HERMIT.Kure: promoteProgT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreProg b -> Translate c m Core b
- Language.HERMIT.Kure: recAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind
- Language.HERMIT.Kure: recAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind
- Language.HERMIT.Kure: recDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind
- Language.HERMIT.Kure: recDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind
- Language.HERMIT.Kure: recDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind
- Language.HERMIT.Kure: recDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> ([(a1, a2)] -> b) -> Translate c m CoreBind b
- Language.HERMIT.Kure: recOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind
- Language.HERMIT.Kure: recT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a) -> ([a] -> b) -> Translate c m CoreBind b
- Language.HERMIT.Kure: reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: reflT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m Coercion b
- Language.HERMIT.Kure: symCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: symCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m Coercion b
- Language.HERMIT.Kure: tickAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: tickAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: tickOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: tickT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreTickish a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
- Language.HERMIT.Kure: transCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: transCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: transCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
- Language.HERMIT.Kure: transCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: tyConAppAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type
- Language.HERMIT.Kure: tyConAppAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type
- Language.HERMIT.Kure: tyConAppCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
- Language.HERMIT.Kure: tyConAppCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
- Language.HERMIT.Kure: tyConAppCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
- Language.HERMIT.Kure: tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: tyConAppOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type
- Language.HERMIT.Kure: tyConAppT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m KindOrType a2) -> (a1 -> [a2] -> b) -> Translate c m Type b
- Language.HERMIT.Kure: tyVarR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyVar -> Rewrite c m Type
- Language.HERMIT.Kure: tyVarT :: (ExtendPath c Crumb, Monad m) => Translate c m TyVar b -> Translate c m Type b
- Language.HERMIT.Kure: type BiRewriteH a = BiRewrite HermitC HermitM a
- Language.HERMIT.Kure: type LensH a b = Lens HermitC HermitM a b
- Language.HERMIT.Kure: type PathH = Path Crumb
- Language.HERMIT.Kure: type RewriteH a = Rewrite HermitC HermitM a
- Language.HERMIT.Kure: type TranslateH a b = Translate HermitC HermitM a b
- Language.HERMIT.Kure: typeR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: typeT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m CoreExpr b
- Language.HERMIT.Kure: unsafeCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: unsafeCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: unsafeCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion
- Language.HERMIT.Kure: unsafeCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
- Language.HERMIT.Kure: varR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr
- Language.HERMIT.Kure: varT :: (ExtendPath c Crumb, Monad m) => Translate c m Id b -> Translate c m CoreExpr b
- Language.HERMIT.Kure.SumTypes: AltCore :: CoreAlt -> Core
- Language.HERMIT.Kure.SumTypes: BindCore :: CoreBind -> Core
- Language.HERMIT.Kure.SumTypes: CoercionCore :: Coercion -> TyCo
- Language.HERMIT.Kure.SumTypes: Core :: Core -> CoreTC
- Language.HERMIT.Kure.SumTypes: DefCore :: CoreDef -> Core
- Language.HERMIT.Kure.SumTypes: ExprCore :: CoreExpr -> Core
- Language.HERMIT.Kure.SumTypes: GutsCore :: ModGuts -> Core
- Language.HERMIT.Kure.SumTypes: ProgCore :: CoreProg -> Core
- Language.HERMIT.Kure.SumTypes: TyCo :: TyCo -> CoreTC
- Language.HERMIT.Kure.SumTypes: TypeCore :: Type -> TyCo
- Language.HERMIT.Kure.SumTypes: data Core
- Language.HERMIT.Kure.SumTypes: data CoreTC
- Language.HERMIT.Kure.SumTypes: data TyCo
- Language.HERMIT.Kure.SumTypes: instance Injection Coercion CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection Coercion TyCo
- Language.HERMIT.Kure.SumTypes: instance Injection Core CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection CoreAlt Core
- Language.HERMIT.Kure.SumTypes: instance Injection CoreAlt CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection CoreBind Core
- Language.HERMIT.Kure.SumTypes: instance Injection CoreBind CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection CoreDef Core
- Language.HERMIT.Kure.SumTypes: instance Injection CoreDef CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection CoreExpr Core
- Language.HERMIT.Kure.SumTypes: instance Injection CoreExpr CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection CoreProg Core
- Language.HERMIT.Kure.SumTypes: instance Injection CoreProg CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection ModGuts Core
- Language.HERMIT.Kure.SumTypes: instance Injection ModGuts CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection TyCo CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection Type CoreTC
- Language.HERMIT.Kure.SumTypes: instance Injection Type TyCo
- Language.HERMIT.Monad: DebugCore :: String -> HermitC -> Core -> DebugMessage
- Language.HERMIT.Monad: DebugTick :: String -> DebugMessage
- Language.HERMIT.Monad: HermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv
- Language.HERMIT.Monad: cloneVarH :: (String -> String) -> Var -> HermitM Var
- Language.HERMIT.Monad: data DebugMessage
- Language.HERMIT.Monad: data HermitM a
- Language.HERMIT.Monad: getStash :: HermitM DefStash
- Language.HERMIT.Monad: hs_debugChan :: HermitMEnv -> DebugMessage -> HermitM ()
- Language.HERMIT.Monad: instance Applicative HermitM
- Language.HERMIT.Monad: instance Functor HermitM
- Language.HERMIT.Monad: instance HasDynFlags HermitM
- Language.HERMIT.Monad: instance Monad HermitM
- Language.HERMIT.Monad: instance MonadCatch HermitM
- Language.HERMIT.Monad: instance MonadIO HermitM
- Language.HERMIT.Monad: instance MonadThings HermitM
- Language.HERMIT.Monad: instance MonadUnique HermitM
- Language.HERMIT.Monad: liftCoreM :: CoreM a -> HermitM a
- Language.HERMIT.Monad: lookupDef :: Label -> HermitM CoreDef
- Language.HERMIT.Monad: mkHermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv
- Language.HERMIT.Monad: newIdH :: String -> Type -> HermitM Id
- Language.HERMIT.Monad: newTyVarH :: String -> Kind -> HermitM TyVar
- Language.HERMIT.Monad: newtype HermitMEnv
- Language.HERMIT.Monad: runHM :: HermitMEnv -> DefStash -> (DefStash -> a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b
- Language.HERMIT.Monad: saveDef :: Label -> CoreDef -> HermitM ()
- Language.HERMIT.Monad: sendDebugMessage :: DebugMessage -> HermitM ()
- Language.HERMIT.Monad: type DefStash = Map Label CoreDef
- Language.HERMIT.Monad: type Label = String
- Language.HERMIT.Optimize: after :: CorePass -> OM () -> OM ()
- Language.HERMIT.Optimize: allPhases :: OM () -> OM ()
- Language.HERMIT.Optimize: at :: TranslateH Core PathH -> OM () -> OM ()
- Language.HERMIT.Optimize: before :: CorePass -> OM () -> OM ()
- Language.HERMIT.Optimize: display :: OM ()
- Language.HERMIT.Optimize: firstPhase :: OM () -> OM ()
- Language.HERMIT.Optimize: interactive :: [External] -> [CommandLineOption] -> OM ()
- Language.HERMIT.Optimize: lastPhase :: OM () -> OM ()
- Language.HERMIT.Optimize: optimize :: ([CommandLineOption] -> OM ()) -> Plugin
- Language.HERMIT.Optimize: phase :: Int -> OM () -> OM ()
- Language.HERMIT.Optimize: query :: (Injection ModGuts g, Walker HermitC g) => TranslateH g a -> OM a
- Language.HERMIT.Optimize: run :: RewriteH Core -> OM ()
- Language.HERMIT.Optimize: setPretty :: (PrettyOptions -> PrettyH CoreTC) -> OM ()
- Language.HERMIT.Optimize: setPrettyOptions :: PrettyOptions -> OM ()
- Language.HERMIT.Parser: AppH :: ExprH -> ExprH -> ExprH
- Language.HERMIT.Parser: CmdName :: String -> ExprH
- Language.HERMIT.Parser: CoreH :: String -> ExprH
- Language.HERMIT.Parser: ListH :: [ExprH] -> ExprH
- Language.HERMIT.Parser: SrcName :: String -> ExprH
- Language.HERMIT.Parser: data ExprH
- Language.HERMIT.Parser: instance Eq ExprH
- Language.HERMIT.Parser: instance Eq Token
- Language.HERMIT.Parser: instance Show ExprH
- Language.HERMIT.Parser: instance Show Token
- Language.HERMIT.Parser: numStmtsH :: [ExprH] -> Int
- Language.HERMIT.Parser: parseStmtsH :: String -> Either String [ExprH]
- Language.HERMIT.Parser: unparseExprH :: ExprH -> String
- Language.HERMIT.ParserCore: instance Eq Token
- Language.HERMIT.ParserCore: instance Show Token
- Language.HERMIT.ParserCore: parseCore :: CoreString -> HermitC -> HermitM CoreExpr
- Language.HERMIT.Plugin: CSE :: CorePass
- Language.HERMIT.Plugin: Desugar :: CorePass
- Language.HERMIT.Plugin: DesugarOpt :: CorePass
- Language.HERMIT.Plugin: FloatInwards :: CorePass
- Language.HERMIT.Plugin: FloatOutwards :: CorePass
- Language.HERMIT.Plugin: LiberateCase :: CorePass
- Language.HERMIT.Plugin: NoOp :: CorePass
- Language.HERMIT.Plugin: Passes :: CorePass
- Language.HERMIT.Plugin: PhaseInfo :: Int -> [CorePass] -> [CorePass] -> PhaseInfo
- Language.HERMIT.Plugin: PluginPass :: String -> CorePass
- Language.HERMIT.Plugin: Prep :: CorePass
- Language.HERMIT.Plugin: PrintCore :: CorePass
- Language.HERMIT.Plugin: RuleCheck :: CorePass
- Language.HERMIT.Plugin: Simplify :: CorePass
- Language.HERMIT.Plugin: SpecConstr :: CorePass
- Language.HERMIT.Plugin: Specialising :: CorePass
- Language.HERMIT.Plugin: StaticArgs :: CorePass
- Language.HERMIT.Plugin: Strictness :: CorePass
- Language.HERMIT.Plugin: Tidy :: CorePass
- Language.HERMIT.Plugin: Unknown :: CorePass
- Language.HERMIT.Plugin: Vectorisation :: CorePass
- Language.HERMIT.Plugin: WorkerWrapper :: CorePass
- Language.HERMIT.Plugin: data CorePass
- Language.HERMIT.Plugin: data PhaseInfo
- Language.HERMIT.Plugin: getCorePass :: CoreToDo -> CorePass
- Language.HERMIT.Plugin: ghcPasses :: [(CorePass, CoreToDo)]
- Language.HERMIT.Plugin: hermitPlugin :: HermitPass -> Plugin
- Language.HERMIT.Plugin: instance Eq CorePass
- Language.HERMIT.Plugin: instance Eq PhaseInfo
- Language.HERMIT.Plugin: instance Read CorePass
- Language.HERMIT.Plugin: instance Read PhaseInfo
- Language.HERMIT.Plugin: instance Show CorePass
- Language.HERMIT.Plugin: instance Show PhaseInfo
- Language.HERMIT.Plugin: phaseNum :: PhaseInfo -> Int
- Language.HERMIT.Plugin: phasesDone :: PhaseInfo -> [CorePass]
- Language.HERMIT.Plugin: phasesLeft :: PhaseInfo -> [CorePass]
- Language.HERMIT.Plugin: type HermitPass = PhaseInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts
- Language.HERMIT.PrettyPrinter.AST: corePrettyH :: PrettyOptions -> PrettyH CoreTC
- Language.HERMIT.PrettyPrinter.Clean: corePrettyH :: PrettyOptions -> PrettyH CoreTC
- Language.HERMIT.PrettyPrinter.Common: Abstract :: ShowOption
- Language.HERMIT.PrettyPrinter.Common: CastSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: CoercionBindSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: CoercionColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: CoercionSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: Color :: SyntaxForColor -> Attr
- Language.HERMIT.PrettyPrinter.Common: ForallSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: IdColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: KeywordColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: Kind :: ShowOption
- Language.HERMIT.PrettyPrinter.Common: LambdaSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: LitColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: Omit :: ShowOption
- Language.HERMIT.PrettyPrinter.Common: PathAttr :: PathH -> Attr
- Language.HERMIT.PrettyPrinter.Common: PrettyOptions :: Bool -> ShowOption -> ShowOption -> ShowOption -> Maybe PathH -> Maybe Int -> Bool -> Float -> Int -> PrettyOptions
- Language.HERMIT.PrettyPrinter.Common: RightArrowSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: Show :: ShowOption
- Language.HERMIT.PrettyPrinter.Common: SpecialFont :: Attr
- Language.HERMIT.PrettyPrinter.Common: SyntaxColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: TranslateCoreTCDocHBox :: (TranslateDocH CoreTC) -> TranslateCoreTCDocHBox
- Language.HERMIT.PrettyPrinter.Common: TranslateDocH :: (PrettyH a -> TranslateH a DocH) -> TranslateDocH a
- Language.HERMIT.PrettyPrinter.Common: TypeBindSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: TypeColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: TypeOfSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: TypeSymbol :: SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: Unicode :: Char -> Unicode
- Language.HERMIT.PrettyPrinter.Common: WarningColor :: SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: attrP :: PathH -> DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: class (RenderSpecial a, Monoid a) => RenderCode a where rStart = mempty rEnd = mempty
- Language.HERMIT.PrettyPrinter.Common: class RenderSpecial a
- Language.HERMIT.PrettyPrinter.Common: coText :: String -> DocH
- Language.HERMIT.PrettyPrinter.Common: coercionColor :: DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: coreRenders :: [(String, Handle -> PrettyOptions -> DocH -> IO ())]
- Language.HERMIT.PrettyPrinter.Common: data Attr
- Language.HERMIT.PrettyPrinter.Common: data PrettyC
- Language.HERMIT.PrettyPrinter.Common: data PrettyOptions
- Language.HERMIT.PrettyPrinter.Common: data ShowOption
- Language.HERMIT.PrettyPrinter.Common: data SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: data SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: data TranslateCoreTCDocHBox
- Language.HERMIT.PrettyPrinter.Common: hlist :: [MDoc a] -> MDoc a
- Language.HERMIT.PrettyPrinter.Common: idColor :: DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: initPrettyC :: PrettyC
- Language.HERMIT.PrettyPrinter.Common: instance AddBindings PrettyC
- Language.HERMIT.PrettyPrinter.Common: instance BoundVars PrettyC
- Language.HERMIT.PrettyPrinter.Common: instance Bounded SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: instance Default PrettyOptions
- Language.HERMIT.PrettyPrinter.Common: instance Enum SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: instance Eq ShowOption
- Language.HERMIT.PrettyPrinter.Common: instance Eq SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: instance ExtendPath PrettyC Crumb
- Language.HERMIT.PrettyPrinter.Common: instance Extern (TranslateDocH CoreTC)
- Language.HERMIT.PrettyPrinter.Common: instance Monoid ASCII
- Language.HERMIT.PrettyPrinter.Common: instance Monoid DebugPretty
- Language.HERMIT.PrettyPrinter.Common: instance Monoid HTML
- Language.HERMIT.PrettyPrinter.Common: instance Monoid LaTeX
- Language.HERMIT.PrettyPrinter.Common: instance Ord ShowOption
- Language.HERMIT.PrettyPrinter.Common: instance Ord SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: instance Read ShowOption
- Language.HERMIT.PrettyPrinter.Common: instance ReadPath PrettyC Crumb
- Language.HERMIT.PrettyPrinter.Common: instance RenderCode ASCII
- Language.HERMIT.PrettyPrinter.Common: instance RenderCode DebugPretty
- Language.HERMIT.PrettyPrinter.Common: instance RenderCode HTML
- Language.HERMIT.PrettyPrinter.Common: instance RenderCode LaTeX
- Language.HERMIT.PrettyPrinter.Common: instance RenderSpecial ASCII
- Language.HERMIT.PrettyPrinter.Common: instance RenderSpecial Char
- Language.HERMIT.PrettyPrinter.Common: instance RenderSpecial DebugPretty
- Language.HERMIT.PrettyPrinter.Common: instance RenderSpecial HTML
- Language.HERMIT.PrettyPrinter.Common: instance RenderSpecial LaTeX
- Language.HERMIT.PrettyPrinter.Common: instance RenderSpecial Unicode
- Language.HERMIT.PrettyPrinter.Common: instance Show Attr
- Language.HERMIT.PrettyPrinter.Common: instance Show HermitMark
- Language.HERMIT.PrettyPrinter.Common: instance Show PrettyOptions
- Language.HERMIT.PrettyPrinter.Common: instance Show ShowOption
- Language.HERMIT.PrettyPrinter.Common: instance Show SpecialSymbol
- Language.HERMIT.PrettyPrinter.Common: instance Show SyntaxForColor
- Language.HERMIT.PrettyPrinter.Common: instance Typeable TranslateCoreTCDocHBox
- Language.HERMIT.PrettyPrinter.Common: keywordColor :: DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: liftPrettyC :: (ReadBindings c, ReadPath c Crumb) => c -> PrettyC
- Language.HERMIT.PrettyPrinter.Common: liftPrettyH :: (ReadBindings c, ReadPath c Crumb) => PrettyH a -> Translate c HermitM a DocH
- Language.HERMIT.PrettyPrinter.Common: markColor :: SyntaxForColor -> DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: newtype TranslateDocH a
- Language.HERMIT.PrettyPrinter.Common: newtype Unicode
- Language.HERMIT.PrettyPrinter.Common: po_coercions :: PrettyOptions -> ShowOption
- Language.HERMIT.PrettyPrinter.Common: po_depth :: PrettyOptions -> Maybe Int
- Language.HERMIT.PrettyPrinter.Common: po_exprTypes :: PrettyOptions -> ShowOption
- Language.HERMIT.PrettyPrinter.Common: po_fullyQualified :: PrettyOptions -> Bool
- Language.HERMIT.PrettyPrinter.Common: po_highlight :: PrettyOptions -> Maybe PathH
- Language.HERMIT.PrettyPrinter.Common: po_notes :: PrettyOptions -> Bool
- Language.HERMIT.PrettyPrinter.Common: po_ribbon :: PrettyOptions -> Float
- Language.HERMIT.PrettyPrinter.Common: po_typesForBinders :: PrettyOptions -> ShowOption
- Language.HERMIT.PrettyPrinter.Common: po_width :: PrettyOptions -> Int
- Language.HERMIT.PrettyPrinter.Common: rDoHighlight :: RenderCode a => Bool -> [Attr] -> a
- Language.HERMIT.PrettyPrinter.Common: rEnd :: RenderCode a => a
- Language.HERMIT.PrettyPrinter.Common: rPutStr :: RenderCode a => String -> a
- Language.HERMIT.PrettyPrinter.Common: rStart :: RenderCode a => a
- Language.HERMIT.PrettyPrinter.Common: renderCode :: RenderCode a => PrettyOptions -> DocH -> a
- Language.HERMIT.PrettyPrinter.Common: renderSpecial :: RenderSpecial a => SpecialSymbol -> a
- Language.HERMIT.PrettyPrinter.Common: specialFont :: DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: tyText :: String -> DocH
- Language.HERMIT.PrettyPrinter.Common: type DocH = MDoc HermitMark
- Language.HERMIT.PrettyPrinter.Common: type PrettyH a = Translate PrettyC HermitM a DocH
- Language.HERMIT.PrettyPrinter.Common: typeColor :: DocH -> DocH
- Language.HERMIT.PrettyPrinter.Common: unTranslateDocH :: TranslateDocH a -> PrettyH a -> TranslateH a DocH
- Language.HERMIT.PrettyPrinter.Common: updateCoShowOption :: ShowOption -> PrettyOptions -> PrettyOptions
- Language.HERMIT.PrettyPrinter.Common: updateTypeShowOption :: ShowOption -> PrettyOptions -> PrettyOptions
- Language.HERMIT.PrettyPrinter.Common: vlist :: [MDoc a] -> MDoc a
- Language.HERMIT.PrettyPrinter.GHC: corePrettyH :: PrettyOptions -> PrettyH CoreTC
- Language.HERMIT.Primitive.AlphaConversion: alpha :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core
- Language.HERMIT.Primitive.AlphaConversion: alphaAlt :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreAlt
- Language.HERMIT.Primitive.AlphaConversion: alphaAltVars :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreAlt
- Language.HERMIT.Primitive.AlphaConversion: alphaAltWith :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Name] -> Rewrite c HermitM CoreAlt
- Language.HERMIT.Primitive.AlphaConversion: alphaCase :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.AlphaConversion: alphaCaseBinder :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.AlphaConversion: alphaConsWith :: (ExtendPath c Crumb, AddBindings c) => [Name] -> Rewrite c HermitM CoreProg
- Language.HERMIT.Primitive.AlphaConversion: alphaLam :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.AlphaConversion: alphaLet :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.AlphaConversion: alphaLetVars :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.AlphaConversion: alphaLetWith :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Name] -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.AlphaConversion: externals :: [External]
- Language.HERMIT.Primitive.AlphaConversion: freshNameGenAvoiding :: Maybe Name -> Set Var -> (String -> String)
- Language.HERMIT.Primitive.AlphaConversion: freshNameGenT :: (BoundVars c, Monad m) => Maybe Name -> Translate c m CoreExpr (String -> String)
- Language.HERMIT.Primitive.AlphaConversion: replaceVarR :: (ExtendPath c Crumb, AddBindings c, Injection a Core, MonadCatch m) => Var -> Var -> Rewrite c m a
- Language.HERMIT.Primitive.AlphaConversion: unshadow :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core
- Language.HERMIT.Primitive.AlphaConversion: visibleVarsT :: (BoundVars c, Monad m) => Translate c m CoreExpr (Set Var)
- Language.HERMIT.Primitive.Common: altVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreAlt [Var]
- Language.HERMIT.Primitive.Common: applyInContextT :: Translate c m a b -> a -> Translate c m x b
- Language.HERMIT.Primitive.Common: bindVarsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreBind [Var]
- Language.HERMIT.Primitive.Common: boundVarsT :: (BoundVars c, Monad m) => Translate c m a (Set Var)
- Language.HERMIT.Primitive.Common: callDataConNameT :: MonadCatch m => Name -> Translate c m CoreExpr (DataCon, [Type], [CoreExpr])
- Language.HERMIT.Primitive.Common: callDataConT :: MonadCatch m => Translate c m CoreExpr (DataCon, [Type], [CoreExpr])
- Language.HERMIT.Primitive.Common: callNameG :: MonadCatch m => Name -> Translate c m CoreExpr ()
- Language.HERMIT.Primitive.Common: callNameT :: MonadCatch m => Name -> Translate c m CoreExpr (CoreExpr, [CoreExpr])
- Language.HERMIT.Primitive.Common: callPredT :: Monad m => (Id -> [CoreExpr] -> Bool) -> Translate c m CoreExpr (CoreExpr, [CoreExpr])
- Language.HERMIT.Primitive.Common: callSaturatedT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])
- Language.HERMIT.Primitive.Common: callT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])
- Language.HERMIT.Primitive.Common: callsR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Name -> Rewrite c m CoreExpr -> Rewrite c m Core
- Language.HERMIT.Primitive.Common: callsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Name -> Translate c m CoreExpr b -> Translate c m Core [b]
- Language.HERMIT.Primitive.Common: caseAltVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [[Var]]
- Language.HERMIT.Primitive.Common: caseVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Var]
- Language.HERMIT.Primitive.Common: caseWildIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Id
- Language.HERMIT.Primitive.Common: consIdsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreProg [Id]
- Language.HERMIT.Primitive.Common: consNonRecIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg Id
- Language.HERMIT.Primitive.Common: consRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg [Id]
- Language.HERMIT.Primitive.Common: defIdT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreDef Id
- Language.HERMIT.Primitive.Common: findBoundVarT :: (BoundVars c, MonadCatch m) => Name -> Translate c m a Var
- Language.HERMIT.Primitive.Common: findId :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m) => Name -> c -> m Id
- Language.HERMIT.Primitive.Common: findIdT :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m, MonadCatch m) => Name -> Translate c m a Id
- Language.HERMIT.Primitive.Common: lamVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var
- Language.HERMIT.Primitive.Common: letNonRecVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var
- Language.HERMIT.Primitive.Common: letRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Id]
- Language.HERMIT.Primitive.Common: letVarsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreExpr [Var]
- Language.HERMIT.Primitive.Common: mapAlts :: (CoreExpr -> CoreExpr) -> [CoreAlt] -> [CoreAlt]
- Language.HERMIT.Primitive.Common: nodups :: Eq a => [a] -> Bool
- Language.HERMIT.Primitive.Common: nonRecVarT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreBind Var
- Language.HERMIT.Primitive.Common: progIdsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreProg [Id]
- Language.HERMIT.Primitive.Common: recIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind [Id]
- Language.HERMIT.Primitive.Common: wrongExprForm :: String -> String
- Language.HERMIT.Primitive.Debug: bracketR :: Injection a Core => String -> RewriteH a -> RewriteH a
- Language.HERMIT.Primitive.Debug: externals :: [External]
- Language.HERMIT.Primitive.Debug: observeFailureR :: Injection a Core => String -> RewriteH a -> RewriteH a
- Language.HERMIT.Primitive.Debug: observeR :: Injection a Core => String -> RewriteH a
- Language.HERMIT.Primitive.Debug: traceR :: String -> RewriteH a
- Language.HERMIT.Primitive.FixPoint: externals :: [External]
- Language.HERMIT.Primitive.FixPoint: fixComputationRule :: BiRewriteH CoreExpr
- Language.HERMIT.Primitive.FixPoint: fixIntro :: RewriteH CoreDef
- Language.HERMIT.Primitive.FixPoint: rollingRule :: BiRewriteH CoreExpr
- Language.HERMIT.Primitive.Fold: externals :: [External]
- Language.HERMIT.Primitive.Fold: foldR :: ReadBindings c => Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Fold: stashFoldAnyR :: ReadBindings c => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Fold: stashFoldR :: ReadBindings c => Label -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.GHC: altFreeVarsExclWildT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreAlt (Id -> Set Var)
- Language.HERMIT.Primitive.GHC: altFreeVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreAlt (Set Var)
- Language.HERMIT.Primitive.GHC: anyCallR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Core -> Rewrite c m Core
- Language.HERMIT.Primitive.GHC: coreEqual :: Core -> Core -> Maybe Bool
- Language.HERMIT.Primitive.GHC: coreExprFreeIds :: CoreExpr -> Set Id
- Language.HERMIT.Primitive.GHC: coreExprFreeVars :: CoreExpr -> Set Var
- Language.HERMIT.Primitive.GHC: equivalent :: (a -> a -> Bool) -> [a] -> Bool
- Language.HERMIT.Primitive.GHC: exprEqual :: CoreExpr -> CoreExpr -> Bool
- Language.HERMIT.Primitive.GHC: exprsEqual :: [CoreExpr] -> Bool
- Language.HERMIT.Primitive.GHC: externals :: [External]
- Language.HERMIT.Primitive.GHC: freeIdsT :: Monad m => Translate c m CoreExpr (Set Id)
- Language.HERMIT.Primitive.GHC: freeTyVarsT :: Monad m => Translate c m Type (Set Var)
- Language.HERMIT.Primitive.GHC: freeVarsT :: Monad m => Translate c m CoreExpr (Set Var)
- Language.HERMIT.Primitive.GHC: inScope :: ReadBindings c => c -> Id -> Bool
- Language.HERMIT.Primitive.GHC: letSubstR :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.GHC: lintExprT :: (BoundVars c, Monad m, HasDynFlags m) => Translate c m CoreExpr String
- Language.HERMIT.Primitive.GHC: lintModuleT :: TranslateH ModGuts String
- Language.HERMIT.Primitive.GHC: lintProgramT :: TranslateH CoreProg String
- Language.HERMIT.Primitive.GHC: rule :: (ReadBindings c, HasCoreRules c) => String -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.GHC: rules :: (ReadBindings c, HasCoreRules c) => [String] -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.GHC: safeLetSubstPlusR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.GHC: safeLetSubstR :: (ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.GHC: showVars :: [Var] -> String
- Language.HERMIT.Primitive.GHC: specConstrR :: RewriteH ModGuts
- Language.HERMIT.Primitive.GHC: substExprR :: Monad m => Var -> CoreExpr -> Rewrite c m CoreExpr
- Language.HERMIT.Primitive.GHC: substR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Var -> CoreExpr -> Rewrite c m Core
- Language.HERMIT.Primitive.GHC: typeFreeVars :: Type -> Set Var
- Language.HERMIT.Primitive.Inline: externals :: [External]
- Language.HERMIT.Primitive.Inline: getUnfolding :: ReadBindings c => Bool -> Bool -> Id -> c -> HermitM (CoreExpr, Int)
- Language.HERMIT.Primitive.Inline: inline :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Inline: inlineCaseBinder :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Inline: inlineName :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Inline: inlineScrutinee :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Inline: inlineTargets :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Translate c HermitM Core [String]
- Language.HERMIT.Primitive.Kure: externals :: [External]
- Language.HERMIT.Primitive.Local: abstract :: (ReadBindings c, MonadCatch m) => Name -> Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local: betaExpand :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local: betaReduce :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local: betaReducePlus :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local: etaExpand :: String -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local: etaReduce :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local: externals :: [External]
- Language.HERMIT.Primitive.Local: flattenModule :: (ExtendPath c Crumb, Monad m) => Rewrite c m ModGuts
- Language.HERMIT.Primitive.Local: flattenProgramR :: Monad m => Rewrite c m CoreProg
- Language.HERMIT.Primitive.Local: flattenProgramT :: Monad m => Translate c m CoreProg CoreBind
- Language.HERMIT.Primitive.Local: multiEtaExpand :: (ExtendPath c Crumb, AddBindings c) => [String] -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local: nonrecToRec :: MonadCatch m => Rewrite c m CoreBind
- Language.HERMIT.Primitive.Local.Case: caseElim :: Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseFloat :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseFloatApp :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseFloatArg :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseFloatCase :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseFloatCast :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseFloatLet :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseReduce :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseReduceDatacon :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseReduceLiteral :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseSplit :: Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseSplitInline :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM Core
- Language.HERMIT.Primitive.Local.Case: caseUnfloat :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseUnfloatApp :: Monad m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Case: caseUnfloatArgs :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Case: externals :: [External]
- Language.HERMIT.Primitive.Local.Cast: castElimRefl :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Cast: castElimSym :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Cast: castElimSymPlus :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Cast: castFloatApp :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Cast: externals :: [External]
- Language.HERMIT.Primitive.Local.Let: externals :: [External]
- Language.HERMIT.Primitive.Local.Let: letElim :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatApp :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatArg :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatCase :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatCast :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatExpr :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatLam :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatLet :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letFloatLetTop :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreProg
- Language.HERMIT.Primitive.Local.Let: letIntro :: Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letNonRecElim :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letRecElim :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letToCase :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Local.Let: letUnfloat :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letUnfloatApp :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letUnfloatCase :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: letUnfloatLam :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Local.Let: reorderNonRecLets :: MonadCatch m => [Name] -> Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Navigation: Application :: Considerable
- Language.HERMIT.Primitive.Navigation: Binding :: Considerable
- Language.HERMIT.Primitive.Navigation: CaseAlt :: Considerable
- Language.HERMIT.Primitive.Navigation: CaseOf :: Considerable
- Language.HERMIT.Primitive.Navigation: Casty :: Considerable
- Language.HERMIT.Primitive.Navigation: Coerce :: Considerable
- Language.HERMIT.Primitive.Navigation: Definition :: Considerable
- Language.HERMIT.Primitive.Navigation: Lambda :: Considerable
- Language.HERMIT.Primitive.Navigation: LetIn :: Considerable
- Language.HERMIT.Primitive.Navigation: Literal :: Considerable
- Language.HERMIT.Primitive.Navigation: Ticky :: Considerable
- Language.HERMIT.Primitive.Navigation: TypeVar :: Considerable
- Language.HERMIT.Primitive.Navigation: Variable :: Considerable
- Language.HERMIT.Primitive.Navigation: bindGroup :: Name -> Core -> Bool
- Language.HERMIT.Primitive.Navigation: bindingGroupOf :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => Name -> Translate c m Core PathH
- Language.HERMIT.Primitive.Navigation: considerConstructT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => Considerable -> Translate c m Core PathH
- Language.HERMIT.Primitive.Navigation: considerName :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => Name -> Translate c m Core PathH
- Language.HERMIT.Primitive.Navigation: considerTargets :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Core [String]
- Language.HERMIT.Primitive.Navigation: considerables :: [(String, Considerable)]
- Language.HERMIT.Primitive.Navigation: data Considerable
- Language.HERMIT.Primitive.Navigation: externals :: [External]
- Language.HERMIT.Primitive.Navigation: namedBinding :: Name -> Core -> Bool
- Language.HERMIT.Primitive.Navigation: nthArgPath :: Monad m => Int -> Translate c m CoreExpr PathH
- Language.HERMIT.Primitive.Navigation: rhsOf :: (ExtendPath c Crumb, AddBindings c, ReadPath c Crumb, MonadCatch m) => Name -> Translate c m Core PathH
- Language.HERMIT.Primitive.Navigation.Crumbs: crumbExternals :: [External]
- Language.HERMIT.Primitive.New: collectLets :: CoreExpr -> ([(Var, CoreExpr)], CoreExpr)
- Language.HERMIT.Primitive.New: externals :: [External]
- Language.HERMIT.Primitive.New: inlineAll :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [Name] -> Rewrite c HermitM Core
- Language.HERMIT.Primitive.New: isVar :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Name -> Translate c m CoreExpr ()
- Language.HERMIT.Primitive.New: letTupleR :: Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.New: parseCoreExprT :: CoreString -> TranslateH a CoreExpr
- Language.HERMIT.Primitive.New: push :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.New: simplifyR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM Core
- Language.HERMIT.Primitive.New: staticArg :: (ExtendPath c Crumb, AddBindings c) => Rewrite c HermitM CoreDef
- Language.HERMIT.Primitive.New: testQuery :: MonadCatch m => Rewrite c m Core -> Translate c m Core String
- Language.HERMIT.Primitive.New: unsafeReplace :: CoreString -> RewriteH CoreExpr
- Language.HERMIT.Primitive.New: unsafeReplaceStash :: String -> RewriteH CoreExpr
- Language.HERMIT.Primitive.Unfold: cleanupUnfoldR :: MonadCatch m => Rewrite c m CoreExpr
- Language.HERMIT.Primitive.Unfold: externals :: [External]
- Language.HERMIT.Primitive.Unfold: rememberR :: Label -> Rewrite c HermitM Core
- Language.HERMIT.Primitive.Unfold: showStashT :: Injection CoreDef a => PrettyH a -> Translate c HermitM a DocH
- Language.HERMIT.Primitive.Unfold: specializeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Unfold: unfoldAnyR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [Name] -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Unfold: unfoldNameR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Unfold: unfoldPredR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => (Id -> [CoreExpr] -> Bool) -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Unfold: unfoldR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Unfold: unfoldSaturatedR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
- Language.HERMIT.Primitive.Unfold: unfoldStashR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr
- Language.HERMIT.Shell.Command: commandLine :: [FilePath] -> Behavior -> [External] -> ScopedKernel -> SAST -> IO ()
- Language.HERMIT.Shell.Command: instance Extern AstEffect
- Language.HERMIT.Shell.Command: instance Extern MetaCommand
- Language.HERMIT.Shell.Command: instance Extern QueryFun
- Language.HERMIT.Shell.Command: instance Extern ShellCommand
- Language.HERMIT.Shell.Command: instance Extern ShellEffect
- Language.HERMIT.Shell.Command: instance Monoid UnicodeTerminal
- Language.HERMIT.Shell.Command: instance RenderCode UnicodeTerminal
- Language.HERMIT.Shell.Command: instance RenderSpecial UnicodeTerminal
- Language.HERMIT.Shell.Command: instance Show CompletionType
- Language.HERMIT.Shell.Command: instance Show Navigation
- Language.HERMIT.Shell.Command: instance Typeable AstEffect
- Language.HERMIT.Shell.Command: instance Typeable MetaCommand
- Language.HERMIT.Shell.Command: instance Typeable QueryFun
- Language.HERMIT.Shell.Command: instance Typeable ShellCommandBox
- Language.HERMIT.Shell.Command: instance Typeable ShellEffect
- Language.HERMIT.Shell.Command: unicodeConsole :: Handle -> PrettyOptions -> DocH -> IO ()
+ HERMIT.Context: CASEALT :: HermitBindingSite
+ HERMIT.Context: CASEWILD :: CoreExpr -> (AltCon, [Var]) -> HermitBindingSite
+ HERMIT.Context: FORALL :: HermitBindingSite
+ HERMIT.Context: LAM :: HermitBindingSite
+ HERMIT.Context: NONREC :: CoreExpr -> HermitBindingSite
+ HERMIT.Context: REC :: CoreExpr -> HermitBindingSite
+ HERMIT.Context: SELFREC :: HermitBindingSite
+ HERMIT.Context: addAltBindings :: AddBindings c => [Var] -> c -> c
+ HERMIT.Context: addBindingGroup :: AddBindings c => CoreBind -> c -> c
+ HERMIT.Context: addCaseWildBinding :: AddBindings c => (Id, CoreExpr, CoreAlt) -> c -> c
+ HERMIT.Context: addDefBinding :: AddBindings c => Id -> c -> c
+ HERMIT.Context: addDefBindingsExcept :: AddBindings c => Int -> [(Id, CoreExpr)] -> c -> c
+ HERMIT.Context: addForallBinding :: AddBindings c => TyVar -> c -> c
+ HERMIT.Context: addHermitBindings :: AddBindings c => [(Var, HermitBindingSite)] -> c -> c
+ HERMIT.Context: addLambdaBinding :: AddBindings c => Var -> c -> c
+ HERMIT.Context: boundIn :: ReadBindings c => Var -> c -> Bool
+ HERMIT.Context: boundVars :: BoundVars c => c -> VarSet
+ HERMIT.Context: class AddBindings c
+ HERMIT.Context: class BoundVars c
+ HERMIT.Context: class HasCoreRules c
+ HERMIT.Context: class HasGlobalRdrEnv c
+ HERMIT.Context: class BoundVars c => ReadBindings c
+ HERMIT.Context: data HermitBindingSite
+ HERMIT.Context: data HermitC
+ HERMIT.Context: findBoundVars :: BoundVars c => Name -> c -> VarSet
+ HERMIT.Context: hermitBindingExpr :: HermitBinding -> KureM CoreExpr
+ HERMIT.Context: hermitBindingSiteExpr :: HermitBindingSite -> KureM CoreExpr
+ HERMIT.Context: hermitBindings :: ReadBindings c => c -> Map Var HermitBinding
+ HERMIT.Context: hermitCoreRules :: HasCoreRules c => c -> [CoreRule]
+ HERMIT.Context: hermitDepth :: ReadBindings c => c -> BindingDepth
+ HERMIT.Context: hermitGlobalRdrEnv :: HasGlobalRdrEnv c => c -> GlobalRdrEnv
+ HERMIT.Context: initHermitC :: ModGuts -> HermitC
+ HERMIT.Context: instance (AddBindings c, AddBindings e) => AddBindings (ExtendContext c e)
+ HERMIT.Context: instance AddBindings (SnocPath crumb)
+ HERMIT.Context: instance AddBindings HermitC
+ HERMIT.Context: instance BoundVars HermitC
+ HERMIT.Context: instance BoundVars VarSet
+ HERMIT.Context: instance ExtendPath HermitC Crumb
+ HERMIT.Context: instance HasCoreRules HermitC
+ HERMIT.Context: instance HasCoreRules [CoreRule]
+ HERMIT.Context: instance HasGlobalRdrEnv GlobalRdrEnv
+ HERMIT.Context: instance HasGlobalRdrEnv HermitC
+ HERMIT.Context: instance ReadBindings HermitC
+ HERMIT.Context: instance ReadPath HermitC Crumb
+ HERMIT.Context: lookupHermitBinding :: (ReadBindings c, Monad m) => Var -> c -> m HermitBinding
+ HERMIT.Context: lookupHermitBindingDepth :: (ReadBindings c, Monad m) => Var -> c -> m BindingDepth
+ HERMIT.Context: lookupHermitBindingSite :: (ReadBindings c, Monad m) => Var -> BindingDepth -> c -> m HermitBindingSite
+ HERMIT.Context: type AbsolutePathH = AbsolutePath Crumb
+ HERMIT.Context: type BindingDepth = Int
+ HERMIT.Context: type HermitBinding = (BindingDepth, HermitBindingSite)
+ HERMIT.Context: type LocalPathH = LocalPath Crumb
+ HERMIT.Core: Alt_Con :: Crumb
+ HERMIT.Core: Alt_RHS :: Crumb
+ HERMIT.Core: Alt_Var :: Int -> Crumb
+ HERMIT.Core: AppCo_Arg :: Crumb
+ HERMIT.Core: AppCo_Fun :: Crumb
+ HERMIT.Core: AppTy_Arg :: Crumb
+ HERMIT.Core: AppTy_Fun :: Crumb
+ HERMIT.Core: App_Arg :: Crumb
+ HERMIT.Core: App_Fun :: Crumb
+ HERMIT.Core: AxiomInstCo_Arg :: Int -> Crumb
+ HERMIT.Core: AxiomInstCo_Axiom :: Crumb
+ HERMIT.Core: AxiomInstCo_Index :: Crumb
+ HERMIT.Core: Case_Alt :: Int -> Crumb
+ HERMIT.Core: Case_Binder :: Crumb
+ HERMIT.Core: Case_Scrutinee :: Crumb
+ HERMIT.Core: Case_Type :: Crumb
+ HERMIT.Core: Cast_Co :: Crumb
+ HERMIT.Core: Cast_Expr :: Crumb
+ HERMIT.Core: CoVarCo_CoVar :: Crumb
+ HERMIT.Core: Co_Co :: Crumb
+ HERMIT.Core: Def :: Id -> CoreExpr -> CoreDef
+ HERMIT.Core: Def_Id :: Crumb
+ HERMIT.Core: Def_RHS :: Crumb
+ HERMIT.Core: ForAllCo_Body :: Crumb
+ HERMIT.Core: ForAllCo_TyVar :: Crumb
+ HERMIT.Core: ForAllTy_Body :: Crumb
+ HERMIT.Core: ForAllTy_Var :: Crumb
+ HERMIT.Core: FunTy_CoDom :: Crumb
+ HERMIT.Core: FunTy_Dom :: Crumb
+ HERMIT.Core: InstCo_Co :: Crumb
+ HERMIT.Core: InstCo_Type :: Crumb
+ HERMIT.Core: LRCo_Co :: Crumb
+ HERMIT.Core: LRCo_LR :: Crumb
+ HERMIT.Core: Lam_Body :: Crumb
+ HERMIT.Core: Lam_Var :: Crumb
+ HERMIT.Core: Let_Bind :: Crumb
+ HERMIT.Core: Let_Body :: Crumb
+ HERMIT.Core: LitTy_TyLit :: Crumb
+ HERMIT.Core: Lit_Lit :: Crumb
+ HERMIT.Core: ModGuts_Prog :: Crumb
+ HERMIT.Core: NonRec_RHS :: Crumb
+ HERMIT.Core: NonRec_Var :: Crumb
+ HERMIT.Core: NthCo_Co :: Crumb
+ HERMIT.Core: NthCo_Int :: Crumb
+ HERMIT.Core: ProgCons :: CoreBind -> CoreProg -> CoreProg
+ HERMIT.Core: ProgCons_Head :: Crumb
+ HERMIT.Core: ProgCons_Tail :: Crumb
+ HERMIT.Core: ProgNil :: CoreProg
+ HERMIT.Core: Rec_Def :: Int -> Crumb
+ HERMIT.Core: Refl_Type :: Crumb
+ HERMIT.Core: SymCo_Co :: Crumb
+ HERMIT.Core: Tick_Expr :: Crumb
+ HERMIT.Core: Tick_Tick :: Crumb
+ HERMIT.Core: TransCo_Left :: Crumb
+ HERMIT.Core: TransCo_Right :: Crumb
+ HERMIT.Core: TyConAppCo_Arg :: Int -> Crumb
+ HERMIT.Core: TyConAppCo_TyCon :: Crumb
+ HERMIT.Core: TyConApp_Arg :: Int -> Crumb
+ HERMIT.Core: TyConApp_TyCon :: Crumb
+ HERMIT.Core: TyVarTy_TyVar :: Crumb
+ HERMIT.Core: Type_Type :: Crumb
+ HERMIT.Core: UnsafeCo_Left :: Crumb
+ HERMIT.Core: UnsafeCo_Right :: Crumb
+ HERMIT.Core: Var_Id :: Crumb
+ HERMIT.Core: altAlphaEq :: CoreAlt -> CoreAlt -> Bool
+ HERMIT.Core: altSyntaxEq :: CoreAlt -> CoreAlt -> Bool
+ HERMIT.Core: altVars :: CoreAlt -> [Var]
+ HERMIT.Core: appCount :: CoreExpr -> Int
+ HERMIT.Core: bindAlphaEq :: CoreBind -> CoreBind -> Bool
+ HERMIT.Core: bindSyntaxEq :: CoreBind -> CoreBind -> Bool
+ HERMIT.Core: bindToVarExprs :: CoreBind -> [(Var, CoreExpr)]
+ HERMIT.Core: bindVars :: CoreBind -> [Var]
+ HERMIT.Core: bindsToProg :: [CoreBind] -> CoreProg
+ HERMIT.Core: coercionAlphaEq :: Coercion -> Coercion -> Bool
+ HERMIT.Core: coercionSyntaxEq :: Coercion -> Coercion -> Bool
+ HERMIT.Core: data CoreDef
+ HERMIT.Core: data CoreProg
+ HERMIT.Core: data Crumb
+ HERMIT.Core: defAlphaEq :: CoreDef -> CoreDef -> Bool
+ HERMIT.Core: defId :: CoreDef -> Id
+ HERMIT.Core: defSyntaxEq :: CoreDef -> CoreDef -> Bool
+ HERMIT.Core: defToIdExpr :: CoreDef -> (Id, CoreExpr)
+ HERMIT.Core: defsToRecBind :: [CoreDef] -> CoreBind
+ HERMIT.Core: deprecatedLeftSibling :: Crumb -> Maybe Crumb
+ HERMIT.Core: deprecatedRightSibling :: Crumb -> Maybe Crumb
+ HERMIT.Core: endoFunType :: Monad m => CoreExpr -> m Type
+ HERMIT.Core: exprAlphaEq :: CoreExpr -> CoreExpr -> Bool
+ HERMIT.Core: exprKindOrType :: CoreExpr -> KindOrType
+ HERMIT.Core: exprSyntaxEq :: CoreExpr -> CoreExpr -> Bool
+ HERMIT.Core: exprTypeM :: Monad m => CoreExpr -> m Type
+ HERMIT.Core: freeIdsExpr :: CoreExpr -> IdSet
+ HERMIT.Core: freeVarsAlt :: CoreAlt -> VarSet
+ HERMIT.Core: freeVarsBind :: CoreBind -> VarSet
+ HERMIT.Core: freeVarsCoercion :: Coercion -> VarSet
+ HERMIT.Core: freeVarsDef :: CoreDef -> VarSet
+ HERMIT.Core: freeVarsExpr :: CoreExpr -> VarSet
+ HERMIT.Core: freeVarsProg :: CoreProg -> VarSet
+ HERMIT.Core: freeVarsType :: Type -> TyVarSet
+ HERMIT.Core: funArgResTypes :: Monad m => CoreExpr -> m (Type, Type)
+ HERMIT.Core: funsWithInverseTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type, Type)
+ HERMIT.Core: instance Eq Crumb
+ HERMIT.Core: instance Read Crumb
+ HERMIT.Core: instance Show Crumb
+ HERMIT.Core: isCoArg :: CoreExpr -> Bool
+ HERMIT.Core: localFreeIdsExpr :: CoreExpr -> VarSet
+ HERMIT.Core: localFreeVarsExpr :: CoreExpr -> VarSet
+ HERMIT.Core: mapAlts :: (CoreExpr -> CoreExpr) -> [CoreAlt] -> [CoreAlt]
+ HERMIT.Core: progAlphaEq :: CoreProg -> CoreProg -> Bool
+ HERMIT.Core: progIds :: CoreProg -> [Id]
+ HERMIT.Core: progSyntaxEq :: CoreProg -> CoreProg -> Bool
+ HERMIT.Core: progToBinds :: CoreProg -> [CoreBind]
+ HERMIT.Core: showCrumbs :: [Crumb] -> String
+ HERMIT.Core: splitFunTypeM :: Monad m => Type -> m (Type, Type)
+ HERMIT.Core: type CoreTickish = Tickish Id
+ HERMIT.Core: typeAlphaEq :: Type -> Type -> Bool
+ HERMIT.Core: typeSyntaxEq :: Type -> Type -> Bool
+ HERMIT.Dictionary: externals :: [External]
+ HERMIT.Dictionary.AlphaConversion: alphaAltR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: alphaAltVarsR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: alphaAltWithR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Name] -> Rewrite c HermitM CoreAlt
+ HERMIT.Dictionary.AlphaConversion: alphaCaseBinderR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaCaseR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLamR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLetR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLetVarsR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaLetWithR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Name] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.AlphaConversion: alphaProgConsWithR :: (ExtendPath c Crumb, AddBindings c) => [Name] -> Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.AlphaConversion: alphaR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.AlphaConversion: externals :: [External]
+ HERMIT.Dictionary.AlphaConversion: freshNameGenAvoiding :: Maybe Name -> VarSet -> (String -> String)
+ HERMIT.Dictionary.AlphaConversion: freshNameGenT :: (BoundVars c, Monad m) => Maybe Name -> Translate c m CoreExpr (String -> String)
+ HERMIT.Dictionary.AlphaConversion: replaceVarR :: (ExtendPath c Crumb, AddBindings c, Injection a Core, MonadCatch m) => Var -> Var -> Rewrite c m a
+ HERMIT.Dictionary.AlphaConversion: unshadowR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.AlphaConversion: visibleVarsT :: (BoundVars c, Monad m) => Translate c m CoreExpr VarSet
+ HERMIT.Dictionary.Common: applyInContextT :: Translate c m a b -> a -> Translate c m x b
+ HERMIT.Dictionary.Common: boundVarsT :: (BoundVars c, Monad m) => Translate c m a VarSet
+ HERMIT.Dictionary.Common: callDataConNameT :: MonadCatch m => Name -> Translate c m CoreExpr (DataCon, [Type], [CoreExpr])
+ HERMIT.Dictionary.Common: callDataConT :: MonadCatch m => Translate c m CoreExpr (DataCon, [Type], [CoreExpr])
+ HERMIT.Dictionary.Common: callNameG :: MonadCatch m => Name -> Translate c m CoreExpr ()
+ HERMIT.Dictionary.Common: callNameT :: MonadCatch m => Name -> Translate c m CoreExpr (CoreExpr, [CoreExpr])
+ HERMIT.Dictionary.Common: callPredT :: Monad m => (Id -> [CoreExpr] -> Bool) -> Translate c m CoreExpr (CoreExpr, [CoreExpr])
+ HERMIT.Dictionary.Common: callSaturatedT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])
+ HERMIT.Dictionary.Common: callT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])
+ HERMIT.Dictionary.Common: callsR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Name -> Rewrite c m CoreExpr -> Rewrite c m Core
+ HERMIT.Dictionary.Common: callsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Name -> Translate c m CoreExpr b -> Translate c m Core [b]
+ HERMIT.Dictionary.Common: caseAltVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [[Var]]
+ HERMIT.Dictionary.Common: caseVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Var]
+ HERMIT.Dictionary.Common: caseWildIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Id
+ HERMIT.Dictionary.Common: exprIsOccurrenceOfT :: (ExtendPath c Crumb, ReadBindings c, Monad m) => Var -> BindingDepth -> Translate c m CoreExpr Bool
+ HERMIT.Dictionary.Common: findBoundVarT :: (BoundVars c, MonadCatch m) => Name -> Translate c m a Var
+ HERMIT.Dictionary.Common: findId :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m) => Name -> c -> m Id
+ HERMIT.Dictionary.Common: findIdT :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m, MonadCatch m) => Name -> Translate c m a Id
+ HERMIT.Dictionary.Common: lamVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var
+ HERMIT.Dictionary.Common: letNonRecVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var
+ HERMIT.Dictionary.Common: letRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Id]
+ HERMIT.Dictionary.Common: letVarsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreExpr [Var]
+ HERMIT.Dictionary.Common: nonRecVarT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreBind Var
+ HERMIT.Dictionary.Common: progConsIdsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreProg [Id]
+ HERMIT.Dictionary.Common: progConsNonRecIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg Id
+ HERMIT.Dictionary.Common: progConsRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg [Id]
+ HERMIT.Dictionary.Common: recIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind [Id]
+ HERMIT.Dictionary.Common: varBindingDepthT :: (ReadBindings c, Monad m) => Var -> Translate c m g BindingDepth
+ HERMIT.Dictionary.Common: varIsOccurrenceOfT :: (ExtendPath c Crumb, ReadBindings c, Monad m) => Var -> BindingDepth -> Translate c m Var Bool
+ HERMIT.Dictionary.Common: wrongExprForm :: String -> String
+ HERMIT.Dictionary.Composite: bashDebugR :: RewriteH Core
+ HERMIT.Dictionary.Composite: bashExtendedWithR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [Rewrite c HermitM Core] -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Composite: bashR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.Composite: bashUsingR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core
+ HERMIT.Dictionary.Composite: externals :: [External]
+ HERMIT.Dictionary.Composite: simplifyR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM Core
+ HERMIT.Dictionary.Composite: unfoldBasicCombinatorR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Debug: bracketR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a
+ HERMIT.Dictionary.Debug: externals :: [External]
+ HERMIT.Dictionary.Debug: observeFailureR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a
+ HERMIT.Dictionary.Debug: observeR :: Injection a CoreTC => String -> RewriteH a
+ HERMIT.Dictionary.Debug: traceR :: String -> RewriteH a
+ HERMIT.Dictionary.FixPoint: externals :: [External]
+ HERMIT.Dictionary.FixPoint: fixComputationRuleBR :: BiRewriteH CoreExpr
+ HERMIT.Dictionary.FixPoint: fixFusionRuleBR :: Maybe (RewriteH CoreExpr, RewriteH CoreExpr) -> Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.FixPoint: fixIntroR :: RewriteH CoreDef
+ HERMIT.Dictionary.FixPoint: fixRollingRuleBR :: BiRewriteH CoreExpr
+ HERMIT.Dictionary.FixPoint: isFixExprT :: TranslateH CoreExpr (Type, CoreExpr)
+ HERMIT.Dictionary.FixPoint: mkFixT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => CoreExpr -> Translate c m z CoreExpr
+ HERMIT.Dictionary.Fold: externals :: [External]
+ HERMIT.Dictionary.Fold: foldR :: ReadBindings c => Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: foldVarR :: ReadBindings c => Var -> Maybe BindingDepth -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: stashFoldAnyR :: ReadBindings c => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Fold: stashFoldR :: ReadBindings c => Label -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Function: externals :: [External]
+ HERMIT.Dictionary.Function: staticArgPosR :: (ExtendPath c Crumb, AddBindings c) => [Int] -> Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgPredR :: (ExtendPath c Crumb, AddBindings c) => ([(Int, Var)] -> HermitM [Int]) -> Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgR :: (ExtendPath c Crumb, AddBindings c) => Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.Function: staticArgTypesR :: (ExtendPath c Crumb, AddBindings c) => Rewrite c HermitM CoreDef
+ HERMIT.Dictionary.GHC: anyCallR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Core -> Rewrite c m Core
+ HERMIT.Dictionary.GHC: arityOf :: ReadBindings c => c -> Id -> Int
+ HERMIT.Dictionary.GHC: dezombifyR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.GHC: dynFlagsT :: HasDynFlags m => Translate c m a DynFlags
+ HERMIT.Dictionary.GHC: externals :: [External]
+ HERMIT.Dictionary.GHC: inScope :: ReadBindings c => c -> Id -> Bool
+ HERMIT.Dictionary.GHC: lintExprT :: (BoundVars c, Monad m, HasDynFlags m) => Translate c m CoreExpr String
+ HERMIT.Dictionary.GHC: lintModuleT :: TranslateH ModGuts String
+ HERMIT.Dictionary.GHC: occurAnalyseAndDezombifyR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core
+ HERMIT.Dictionary.GHC: occurAnalyseChangedR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core
+ HERMIT.Dictionary.GHC: occurAnalyseExprChangedR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.GHC: occurAnalyseR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core
+ HERMIT.Dictionary.GHC: rule :: (ReadBindings c, HasCoreRules c) => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.GHC: rules :: (ReadBindings c, HasCoreRules c) => [String] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.GHC: specConstrR :: RewriteH ModGuts
+ HERMIT.Dictionary.GHC: substExprR :: Monad m => Var -> CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Dictionary.GHC: substR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Var -> CoreExpr -> Rewrite c m Core
+ HERMIT.Dictionary.Inline: AllBinders :: InlineConfig
+ HERMIT.Dictionary.Inline: Alternative :: CaseBinderInlineOption
+ HERMIT.Dictionary.Inline: CaseBinderOnly :: CaseBinderInlineOption -> InlineConfig
+ HERMIT.Dictionary.Inline: Scrutinee :: CaseBinderInlineOption
+ HERMIT.Dictionary.Inline: configurableInlineR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => InlineConfig -> (Translate c HermitM Id Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: data CaseBinderInlineOption
+ HERMIT.Dictionary.Inline: data InlineConfig
+ HERMIT.Dictionary.Inline: externals :: [External]
+ HERMIT.Dictionary.Inline: getUnfoldingT :: ReadBindings c => InlineConfig -> Translate c HermitM Id (CoreExpr, BindingDepth -> Bool)
+ HERMIT.Dictionary.Inline: inlineCaseAlternativeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineCaseScrutineeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineNameR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineNamesR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [Name] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Inline: inlineTargetsT :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Translate c HermitM Core [String]
+ HERMIT.Dictionary.Inline: instance Eq CaseBinderInlineOption
+ HERMIT.Dictionary.Inline: instance Eq InlineConfig
+ HERMIT.Dictionary.Inline: instance Show CaseBinderInlineOption
+ HERMIT.Dictionary.Inline: instance Show InlineConfig
+ HERMIT.Dictionary.Kure: externals :: [External]
+ HERMIT.Dictionary.Local: abstractR :: (ReadBindings c, MonadCatch m) => Name -> Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local: betaExpandR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local: betaReducePlusR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local: betaReduceR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local: etaExpandR :: String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local: etaReduceR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local: externals :: [External]
+ HERMIT.Dictionary.Local: flattenModuleR :: (ExtendPath c Crumb, Monad m) => Rewrite c m ModGuts
+ HERMIT.Dictionary.Local: flattenProgramR :: Monad m => Rewrite c m CoreProg
+ HERMIT.Dictionary.Local: flattenProgramT :: Monad m => Translate c m CoreProg CoreBind
+ HERMIT.Dictionary.Local: multiEtaExpandR :: (ExtendPath c Crumb, AddBindings c) => [String] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local: pushR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, HasGlobalRdrEnv c) => Maybe (Rewrite c HermitM CoreExpr) -> (Id -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Bind: externals :: [External]
+ HERMIT.Dictionary.Local.Bind: nonrecToRecR :: MonadCatch m => Rewrite c m CoreBind
+ HERMIT.Dictionary.Local.Bind: recToNonrecR :: MonadCatch m => Rewrite c m CoreBind
+ HERMIT.Dictionary.Local.Case: caseElimInlineScrutineeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimMergeAltsR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimR :: Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseElimSeqR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatAppR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatArgR :: (ExtendPath c Crumb, AddBindings c, BoundVars c, HasGlobalRdrEnv c) => Maybe (CoreExpr, Maybe (Rewrite c HermitM CoreExpr)) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatCaseR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatCastR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatLetR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseFloatR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseInlineAlternativeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseInlineScrutineeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseIntroSeqR :: Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseMergeAltsR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Case: caseMergeAltsWithWildR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceDataconR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceIdR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceLiteralR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Case: caseReduceR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseSplitInlineR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Local.Case: caseSplitR :: Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Case: caseUnfloatAppR :: Monad m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Case: caseUnfloatArgsR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Case: caseUnfloatR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Case: externals :: [External]
+ HERMIT.Dictionary.Local.Cast: castElimReflR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Cast: castElimSymPlusR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Cast: castElimSymR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Cast: castFloatAppR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Cast: externals :: [External]
+ HERMIT.Dictionary.Local.Let: externals :: [External]
+ HERMIT.Dictionary.Local.Let: letElimR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatAppR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatArgR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatCaseR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatCastR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatExprR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatLamR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatLetR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letFloatTopR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg
+ HERMIT.Dictionary.Local.Let: letIntroR :: String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letNonRecElimR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letNonRecSubstR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letNonRecSubstSafeR :: (AddBindings c, ExtendPath c Crumb, ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letRecElimR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letSubstR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letSubstSafeR :: (AddBindings c, ExtendPath c Crumb, ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letToCaseR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letTupleR :: String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Local.Let: letUnfloatAppR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letUnfloatCaseR :: MonadCatch m => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letUnfloatLamR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: letUnfloatR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Local.Let: reorderNonRecLetsR :: MonadCatch m => [Name] -> Rewrite c m CoreExpr
+ HERMIT.Dictionary.Navigation: Application :: Considerable
+ HERMIT.Dictionary.Navigation: Binding :: Considerable
+ HERMIT.Dictionary.Navigation: CaseAlt :: Considerable
+ HERMIT.Dictionary.Navigation: CaseOf :: Considerable
+ HERMIT.Dictionary.Navigation: Casty :: Considerable
+ HERMIT.Dictionary.Navigation: CoercionExpr :: Considerable
+ HERMIT.Dictionary.Navigation: Definition :: Considerable
+ HERMIT.Dictionary.Navigation: Lambda :: Considerable
+ HERMIT.Dictionary.Navigation: LetExpr :: Considerable
+ HERMIT.Dictionary.Navigation: Literal :: Considerable
+ HERMIT.Dictionary.Navigation: Ticky :: Considerable
+ HERMIT.Dictionary.Navigation: TypeExpr :: Considerable
+ HERMIT.Dictionary.Navigation: Variable :: Considerable
+ HERMIT.Dictionary.Navigation: bindingGroupOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m CoreTC LocalPathH
+ HERMIT.Dictionary.Navigation: bindingGroupOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet
+ HERMIT.Dictionary.Navigation: bindingOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m CoreTC LocalPathH
+ HERMIT.Dictionary.Navigation: bindingOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet
+ HERMIT.Dictionary.Navigation: considerConstructT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => Considerable -> Translate c m Core LocalPathH
+ HERMIT.Dictionary.Navigation: considerables :: [(String, Considerable)]
+ HERMIT.Dictionary.Navigation: data Considerable
+ HERMIT.Dictionary.Navigation: externals :: [External]
+ HERMIT.Dictionary.Navigation: nthArgPath :: Monad m => Int -> Translate c m CoreExpr LocalPathH
+ HERMIT.Dictionary.Navigation: occurrenceOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m CoreTC LocalPathH
+ HERMIT.Dictionary.Navigation: occurrenceOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet
+ HERMIT.Dictionary.Navigation: parentOfT :: MonadCatch m => Translate c m g LocalPathH -> Translate c m g LocalPathH
+ HERMIT.Dictionary.Navigation: rhsOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m Core LocalPathH
+ HERMIT.Dictionary.Navigation: rhsOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet
+ HERMIT.Dictionary.Navigation.Crumbs: crumbExternals :: [External]
+ HERMIT.Dictionary.New: externals :: [External]
+ HERMIT.Dictionary.New: isVar :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Name -> Translate c m CoreExpr ()
+ HERMIT.Dictionary.New: letNonRecIntroR :: String -> CoreString -> RewriteH CoreExpr
+ HERMIT.Dictionary.New: progNonRecIntroR :: String -> CoreString -> RewriteH CoreProg
+ HERMIT.Dictionary.Query: compareBoundIdsT :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Id -> Id -> Translate c HermitM x ()
+ HERMIT.Dictionary.Query: compareCoreAtT :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => Translate c m Core LocalPathH -> Translate c m Core LocalPathH -> Translate c m Core ()
+ HERMIT.Dictionary.Query: externals :: [External]
+ HERMIT.Dictionary.Query: infoT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, BoundVars c, HasDynFlags m, MonadCatch m) => Translate c m CoreTC String
+ HERMIT.Dictionary.Reasoning: externals :: [External]
+ HERMIT.Dictionary.Reasoning: retractionBR :: Maybe (Rewrite c HermitM CoreExpr) -> CoreExpr -> CoreExpr -> BiRewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Reasoning: verifyEqualityCommonTargetT :: MonadCatch m => CoreExpr -> CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Translate c m a ()
+ HERMIT.Dictionary.Reasoning: verifyEqualityLeftToRightT :: MonadCatch m => CoreExpr -> CoreExpr -> Rewrite c m CoreExpr -> Translate c m a ()
+ HERMIT.Dictionary.Reasoning: verifyIsomorphismT :: CoreExpr -> CoreExpr -> Rewrite c HermitM CoreExpr -> Rewrite c HermitM CoreExpr -> Translate c HermitM a ()
+ HERMIT.Dictionary.Reasoning: verifyRetractionT :: CoreExpr -> CoreExpr -> Rewrite c HermitM CoreExpr -> Translate c HermitM a ()
+ HERMIT.Dictionary.Undefined: errorToUndefinedR :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: externals :: [External]
+ HERMIT.Dictionary.Undefined: isUndefinedValT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Translate c m CoreExpr ()
+ HERMIT.Dictionary.Undefined: mkUndefinedValT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Type -> Translate c m a CoreExpr
+ HERMIT.Dictionary.Undefined: replaceWithUndefinedR :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedAppR :: (BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCaseAltsR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCaseScrutineeR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedCastR :: (BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedLamR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedLetR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: undefinedTickR :: (BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Undefined: verifyStrictT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => CoreExpr -> Rewrite c m CoreExpr -> Translate c m a ()
+ HERMIT.Dictionary.Unfold: cleanupUnfoldR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr
+ HERMIT.Dictionary.Unfold: externals :: [External]
+ HERMIT.Dictionary.Unfold: rememberR :: Label -> Rewrite c HermitM Core
+ HERMIT.Dictionary.Unfold: showStashT :: Injection CoreDef a => PrettyC -> PrettyH a -> Translate c HermitM a DocH
+ HERMIT.Dictionary.Unfold: specializeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldNameR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Name -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldNamesR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [Name] -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldPredR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => (Id -> [CoreExpr] -> Bool) -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldSaturatedR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unfold: unfoldStashR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr
+ HERMIT.Dictionary.Unsafe: externals :: [External]
+ HERMIT.Dictionary.Unsafe: unsafeReplaceR :: CoreString -> RewriteH CoreExpr
+ HERMIT.Dictionary.Unsafe: unsafeReplaceStashR :: String -> RewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Common: A :: WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: B :: WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: C :: WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: WWAssumption :: WWAssumptionTag -> (RewriteH CoreExpr) -> WWAssumption
+ HERMIT.Dictionary.WorkerWrapper.Common: data WWAssumption
+ HERMIT.Dictionary.WorkerWrapper.Common: data WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: instance Eq WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: instance Ord WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: instance Read WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: instance Show WWAssumptionTag
+ HERMIT.Dictionary.WorkerWrapper.Common: workLabel :: Label
+ HERMIT.Dictionary.WorkerWrapper.Fix: externals :: [External]
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwAssA :: Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwAssB :: Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwAssC :: Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwFacBR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwFusionBR :: BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwGenerateFusionR :: Maybe WWAssumption -> RewriteH Core
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwSplitR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> RewriteH CoreDef
+ HERMIT.Dictionary.WorkerWrapper.Fix: wwSplitStaticArg :: Int -> [Int] -> Maybe WWAssumption -> CoreString -> CoreString -> RewriteH CoreDef
+ HERMIT.Dictionary.WorkerWrapper.FixResult: externals :: [External]
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultAssA :: Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultAssB :: Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultAssC :: Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultFacBR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultFusionBR :: BiRewriteH CoreExpr
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultGenerateFusionR :: Maybe WWAssumption -> RewriteH Core
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultSplitR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> RewriteH CoreDef
+ HERMIT.Dictionary.WorkerWrapper.FixResult: wwResultSplitStaticArg :: Int -> [Int] -> Maybe WWAssumption -> CoreString -> CoreString -> RewriteH CoreDef
+ HERMIT.External: (.&) :: (Tag a, Tag b) => a -> b -> TagE
+ HERMIT.External: (.+) :: Tag a => External -> a -> External
+ HERMIT.External: (.||) :: (Tag a, Tag b) => a -> b -> TagE
+ HERMIT.External: BiRewriteCoreBox :: (BiRewriteH Core) -> BiRewriteCoreBox
+ HERMIT.External: Commute :: CmdTag
+ HERMIT.External: Context :: CmdTag
+ HERMIT.External: CoreBox :: CoreString -> CoreBox
+ HERMIT.External: CoreString :: String -> CoreString
+ HERMIT.External: CrumbBox :: Crumb -> CrumbBox
+ HERMIT.External: Debug :: CmdTag
+ HERMIT.External: Deep :: CmdTag
+ HERMIT.External: Deprecated :: CmdTag
+ HERMIT.External: Eval :: CmdTag
+ HERMIT.External: Experiment :: CmdTag
+ HERMIT.External: IntBox :: Int -> IntBox
+ HERMIT.External: IntListBox :: [Int] -> IntListBox
+ HERMIT.External: Introduce :: CmdTag
+ HERMIT.External: KURE :: CmdTag
+ HERMIT.External: Loop :: CmdTag
+ HERMIT.External: NameBox :: (Name) -> NameBox
+ HERMIT.External: NameListBox :: [Name] -> NameListBox
+ HERMIT.External: Navigation :: CmdTag
+ HERMIT.External: PathBox :: LocalPathH -> PathBox
+ HERMIT.External: PreCondition :: CmdTag
+ HERMIT.External: Predicate :: CmdTag
+ HERMIT.External: Query :: CmdTag
+ HERMIT.External: RewriteCoreBox :: (RewriteH Core) -> RewriteCoreBox
+ HERMIT.External: RewriteCoreListBox :: [RewriteH Core] -> RewriteCoreListBox
+ HERMIT.External: RewriteCoreTCBox :: (RewriteH CoreTC) -> RewriteCoreTCBox
+ HERMIT.External: Shallow :: CmdTag
+ HERMIT.External: Shell :: CmdTag
+ HERMIT.External: StringBox :: String -> StringBox
+ HERMIT.External: StringListBox :: [String] -> StringListBox
+ HERMIT.External: TODO :: CmdTag
+ HERMIT.External: TagBox :: TagE -> TagBox
+ HERMIT.External: TranslateCoreCheckBox :: (TranslateH Core ()) -> TranslateCoreCheckBox
+ HERMIT.External: TranslateCorePathBox :: (TranslateH Core LocalPathH) -> TranslateCorePathBox
+ HERMIT.External: TranslateCoreStringBox :: (TranslateH Core String) -> TranslateCoreStringBox
+ HERMIT.External: TranslateCoreTCCheckBox :: (TranslateH CoreTC ()) -> TranslateCoreTCCheckBox
+ HERMIT.External: TranslateCoreTCPathBox :: (TranslateH CoreTC LocalPathH) -> TranslateCoreTCPathBox
+ HERMIT.External: TranslateCoreTCStringBox :: (TranslateH CoreTC String) -> TranslateCoreTCStringBox
+ HERMIT.External: Unsafe :: CmdTag
+ HERMIT.External: VersionControl :: CmdTag
+ HERMIT.External: box :: Extern a => a -> Box a
+ HERMIT.External: class Typeable (Box a) => Extern a where type family Box a
+ HERMIT.External: class Tag a
+ HERMIT.External: data BiRewriteCoreBox
+ HERMIT.External: data CmdTag
+ HERMIT.External: data CoreBox
+ HERMIT.External: data CrumbBox
+ HERMIT.External: data External
+ HERMIT.External: data IntBox
+ HERMIT.External: data IntListBox
+ HERMIT.External: data NameBox
+ HERMIT.External: data NameListBox
+ HERMIT.External: data PathBox
+ HERMIT.External: data RewriteCoreBox
+ HERMIT.External: data RewriteCoreListBox
+ HERMIT.External: data RewriteCoreTCBox
+ HERMIT.External: data StringBox
+ HERMIT.External: data StringListBox
+ HERMIT.External: data TagBox
+ HERMIT.External: data TagE :: *
+ HERMIT.External: data TranslateCoreCheckBox
+ HERMIT.External: data TranslateCorePathBox
+ HERMIT.External: data TranslateCoreStringBox
+ HERMIT.External: data TranslateCoreTCCheckBox
+ HERMIT.External: data TranslateCoreTCPathBox
+ HERMIT.External: data TranslateCoreTCStringBox
+ HERMIT.External: dictionaryOfTags :: [(CmdTag, String)]
+ HERMIT.External: externDyn :: External -> Dynamic
+ HERMIT.External: externHelp :: External -> ExternalHelp
+ HERMIT.External: externName :: External -> ExternalName
+ HERMIT.External: externTags :: External -> [CmdTag]
+ HERMIT.External: external :: Extern a => ExternalName -> a -> ExternalHelp -> External
+ HERMIT.External: instance (Extern a, Extern b) => Extern (a -> b)
+ HERMIT.External: instance Bounded CmdTag
+ HERMIT.External: instance Enum CmdTag
+ HERMIT.External: instance Eq CmdTag
+ HERMIT.External: instance Extern (BiRewriteH Core)
+ HERMIT.External: instance Extern (RewriteH Core)
+ HERMIT.External: instance Extern (RewriteH CoreTC)
+ HERMIT.External: instance Extern (TranslateH Core ())
+ HERMIT.External: instance Extern (TranslateH Core LocalPathH)
+ HERMIT.External: instance Extern (TranslateH Core String)
+ HERMIT.External: instance Extern (TranslateH CoreTC ())
+ HERMIT.External: instance Extern (TranslateH CoreTC LocalPathH)
+ HERMIT.External: instance Extern (TranslateH CoreTC String)
+ HERMIT.External: instance Extern CoreString
+ HERMIT.External: instance Extern Crumb
+ HERMIT.External: instance Extern Int
+ HERMIT.External: instance Extern LocalPathH
+ HERMIT.External: instance Extern Name
+ HERMIT.External: instance Extern String
+ HERMIT.External: instance Extern TagE
+ HERMIT.External: instance Extern [Int]
+ HERMIT.External: instance Extern [Name]
+ HERMIT.External: instance Extern [RewriteH Core]
+ HERMIT.External: instance Extern [String]
+ HERMIT.External: instance Read CmdTag
+ HERMIT.External: instance Show CmdTag
+ HERMIT.External: instance Tag CmdTag
+ HERMIT.External: instance Tag TagE
+ HERMIT.External: instance Typeable BiRewriteCoreBox
+ HERMIT.External: instance Typeable CoreBox
+ HERMIT.External: instance Typeable CrumbBox
+ HERMIT.External: instance Typeable IntBox
+ HERMIT.External: instance Typeable IntListBox
+ HERMIT.External: instance Typeable NameBox
+ HERMIT.External: instance Typeable NameListBox
+ HERMIT.External: instance Typeable PathBox
+ HERMIT.External: instance Typeable RewriteCoreBox
+ HERMIT.External: instance Typeable RewriteCoreListBox
+ HERMIT.External: instance Typeable RewriteCoreTCBox
+ HERMIT.External: instance Typeable StringBox
+ HERMIT.External: instance Typeable StringListBox
+ HERMIT.External: instance Typeable TagBox
+ HERMIT.External: instance Typeable TranslateCoreCheckBox
+ HERMIT.External: instance Typeable TranslateCorePathBox
+ HERMIT.External: instance Typeable TranslateCoreStringBox
+ HERMIT.External: instance Typeable TranslateCoreTCCheckBox
+ HERMIT.External: instance Typeable TranslateCoreTCPathBox
+ HERMIT.External: instance Typeable TranslateCoreTCStringBox
+ HERMIT.External: matchingExternals :: (Extern tr, Tag t) => t -> [External] -> [(External, tr)]
+ HERMIT.External: newtype CoreString
+ HERMIT.External: notT :: Tag a => a -> TagE
+ HERMIT.External: remTag :: Tag a => a -> External -> External
+ HERMIT.External: tagMatch :: Tag a => a -> External -> Bool
+ HERMIT.External: toDictionary :: [External] -> Dictionary
+ HERMIT.External: toHelp :: [External] -> Map ExternalName ExternalHelp
+ HERMIT.External: type Dictionary = Map ExternalName [Dynamic]
+ HERMIT.External: type ExternalHelp = [String]
+ HERMIT.External: type ExternalName = String
+ HERMIT.External: unCoreString :: CoreString -> String
+ HERMIT.External: unbox :: Extern a => Box a -> a
+ HERMIT.GHC: AppTy :: Type -> Type -> Type
+ HERMIT.GHC: ForAllTy :: Var -> Type -> Type
+ HERMIT.GHC: FunTy :: Type -> Type -> Type
+ HERMIT.GHC: LitTy :: TyLit -> Type
+ HERMIT.GHC: NumTyLit :: Integer -> TyLit
+ HERMIT.GHC: Pair :: a -> a -> Pair a
+ HERMIT.GHC: ProgramError :: String -> GhcException
+ HERMIT.GHC: StrTyLit :: FastString -> TyLit
+ HERMIT.GHC: TyConApp :: TyCon -> [KindOrType] -> Type
+ HERMIT.GHC: TyVarTy :: Var -> Type
+ HERMIT.GHC: alphaTyVars :: [TyVar]
+ HERMIT.GHC: cmpString2Name :: String -> Name -> Bool
+ HERMIT.GHC: cmpString2Var :: String -> Var -> Bool
+ HERMIT.GHC: cmpTHName2Name :: Name -> Name -> Bool
+ HERMIT.GHC: cmpTHName2Var :: Name -> Var -> Bool
+ HERMIT.GHC: data GhcException :: *
+ HERMIT.GHC: data Pair a :: * -> *
+ HERMIT.GHC: data TyLit :: *
+ HERMIT.GHC: data Type :: *
+ HERMIT.GHC: exprArity :: CoreExpr -> Arity
+ HERMIT.GHC: findNamesFromString :: GlobalRdrEnv -> String -> [Name]
+ HERMIT.GHC: findNamesFromTH :: GlobalRdrEnv -> Name -> [Name]
+ HERMIT.GHC: fqName :: Name -> String
+ HERMIT.GHC: instance MonadIO CoreM
+ HERMIT.GHC: instance Monoid VarSet
+ HERMIT.GHC: isKind :: Kind -> Bool
+ HERMIT.GHC: isLiftedTypeKindCon :: TyCon -> Bool
+ HERMIT.GHC: liftIO :: MonadIO m => forall a. IO a -> m a
+ HERMIT.GHC: name2THName :: Name -> Name
+ HERMIT.GHC: notElemVarSet :: Var -> VarSet -> Bool
+ HERMIT.GHC: occurAnalyseExpr :: CoreExpr -> CoreExpr
+ HERMIT.GHC: pFst :: Pair a -> a
+ HERMIT.GHC: pSnd :: Pair a -> a
+ HERMIT.GHC: ppIdInfo :: Id -> IdInfo -> SDoc
+ HERMIT.GHC: showVarSet :: VarSet -> String
+ HERMIT.GHC: thRdrNameGuesses :: Name -> [RdrName]
+ HERMIT.GHC: throwGhcException :: GhcException -> a
+ HERMIT.GHC: uqName :: NamedThing nm => nm -> String
+ HERMIT.GHC: var2String :: Var -> String
+ HERMIT.GHC: var2THName :: Var -> Name
+ HERMIT.GHC: varSetToStrings :: VarSet -> [String]
+ HERMIT.GHC: zapVarOccInfo :: Var -> Var
+ HERMIT.Interp: data Interp :: * -> *
+ HERMIT.Interp: instance Functor Interp
+ HERMIT.Interp: interp :: Typeable a => (a -> b) -> Interp b
+ HERMIT.Interp: interpExprH :: Monad m => Dictionary -> [Interp a] -> ExprH -> m a
+ HERMIT.Kernel: abortK :: Kernel -> IO ()
+ HERMIT.Kernel: applyK :: Kernel -> AST -> RewriteH ModGuts -> HermitMEnv -> IO (KureM AST)
+ HERMIT.Kernel: data AST
+ HERMIT.Kernel: data Kernel
+ HERMIT.Kernel: deleteK :: Kernel -> AST -> IO ()
+ HERMIT.Kernel: hermitKernel :: (Kernel -> AST -> IO ()) -> ModGuts -> CoreM ModGuts
+ HERMIT.Kernel: instance Eq AST
+ HERMIT.Kernel: instance Ord AST
+ HERMIT.Kernel: instance Show AST
+ HERMIT.Kernel: listK :: Kernel -> IO [AST]
+ HERMIT.Kernel: queryK :: Kernel -> forall a. AST -> TranslateH ModGuts a -> HermitMEnv -> IO (KureM a)
+ HERMIT.Kernel: resumeK :: Kernel -> AST -> IO ()
+ HERMIT.Kernel.Scoped: L :: Direction
+ HERMIT.Kernel.Scoped: R :: Direction
+ HERMIT.Kernel.Scoped: SAST :: Int -> SAST
+ HERMIT.Kernel.Scoped: ScopedKernel :: (forall m. (MonadIO m, MonadCatch m) => SAST -> m ()) -> (forall m. MonadIO m => m ()) -> (forall g m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => RewriteH g -> HermitMEnv -> SAST -> m SAST) -> (forall g a m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => TranslateH g a -> HermitMEnv -> SAST -> m a) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m ()) -> (forall m. MonadIO m => m [SAST]) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m [PathH]) -> (forall m. (MonadIO m, MonadCatch m) => (LocalPathH -> LocalPathH) -> HermitMEnv -> SAST -> m SAST) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST) -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST) -> Kernel -> (forall m. (MonadIO m, MonadCatch m) => SAST -> m AST) -> ScopedKernel
+ HERMIT.Kernel.Scoped: T :: Direction
+ HERMIT.Kernel.Scoped: U :: Direction
+ HERMIT.Kernel.Scoped: abortS :: ScopedKernel -> forall m. MonadIO m => m ()
+ HERMIT.Kernel.Scoped: applyS :: ScopedKernel -> forall g m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => RewriteH g -> HermitMEnv -> SAST -> m SAST
+ HERMIT.Kernel.Scoped: beginScopeS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST
+ HERMIT.Kernel.Scoped: data Direction
+ HERMIT.Kernel.Scoped: data ScopedKernel
+ HERMIT.Kernel.Scoped: deleteS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => SAST -> m ()
+ HERMIT.Kernel.Scoped: endScopeS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => SAST -> m SAST
+ HERMIT.Kernel.Scoped: instance Eq Direction
+ HERMIT.Kernel.Scoped: instance Eq SAST
+ HERMIT.Kernel.Scoped: instance Ord SAST
+ HERMIT.Kernel.Scoped: instance Show Direction
+ HERMIT.Kernel.Scoped: instance Show SAST
+ HERMIT.Kernel.Scoped: kernelS :: ScopedKernel -> Kernel
+ HERMIT.Kernel.Scoped: listS :: ScopedKernel -> forall m. MonadIO m => m [SAST]
+ HERMIT.Kernel.Scoped: modPathS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => (LocalPathH -> LocalPathH) -> HermitMEnv -> SAST -> m SAST
+ HERMIT.Kernel.Scoped: moveLocally :: Direction -> LocalPathH -> LocalPathH
+ HERMIT.Kernel.Scoped: newtype SAST
+ HERMIT.Kernel.Scoped: pathS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => SAST -> m [PathH]
+ HERMIT.Kernel.Scoped: queryS :: ScopedKernel -> forall g a m. (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g) => TranslateH g a -> HermitMEnv -> SAST -> m a
+ HERMIT.Kernel.Scoped: resumeS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => SAST -> m ()
+ HERMIT.Kernel.Scoped: scopedKernel :: (ScopedKernel -> SAST -> IO ()) -> ModGuts -> CoreM ModGuts
+ HERMIT.Kernel.Scoped: toASTS :: ScopedKernel -> forall m. (MonadIO m, MonadCatch m) => SAST -> m AST
+ HERMIT.Kernel.Scoped: type LocalPath = SnocPath
+ HERMIT.Kure: altAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt
+ HERMIT.Kure: altAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt
+ HERMIT.Kure: altOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt
+ HERMIT.Kure: altT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m AltCon a1 -> (Int -> Translate c m Var a2) -> Translate c m CoreExpr a3 -> (a1 -> [a2] -> a3 -> b) -> Translate c m CoreAlt b
+ HERMIT.Kure: appAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: appAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: appCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: appCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: appCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: appCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
+ HERMIT.Kure: appOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: appT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: appTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: appTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: appTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: appTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b
+ HERMIT.Kure: axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
+ HERMIT.Kure: axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
+ HERMIT.Kure: axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
+ HERMIT.Kure: axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoAxiom a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b
+ HERMIT.Kure: caseAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> Rewrite c m CoreAlt) -> Rewrite c m CoreExpr
+ HERMIT.Kure: caseAltAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> (Rewrite c m AltCon, Int -> Rewrite c m Var, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr
+ HERMIT.Kure: caseAltAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> (Rewrite c m AltCon, Int -> Rewrite c m Var, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr
+ HERMIT.Kure: caseAltOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> (Rewrite c m AltCon, Int -> Rewrite c m Var, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr
+ HERMIT.Kure: caseAltT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr sc -> Translate c m Id w -> Translate c m Type ty -> (Int -> (Translate c m AltCon con, Int -> Translate c m Var v, Translate c m CoreExpr rhs)) -> (sc -> w -> ty -> [(con, [v], rhs)] -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: caseAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> Rewrite c m CoreAlt) -> Rewrite c m CoreExpr
+ HERMIT.Kure: caseOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Id -> Rewrite c m Type -> (Int -> Rewrite c m CoreAlt) -> Rewrite c m CoreExpr
+ HERMIT.Kure: caseT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr e -> Translate c m Id w -> Translate c m Type ty -> (Int -> Translate c m CoreAlt alt) -> (e -> w -> ty -> [alt] -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: castAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr
+ HERMIT.Kure: castAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr
+ HERMIT.Kure: castOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr
+ HERMIT.Kure: castT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: coVarCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoVar -> Rewrite c m Coercion
+ HERMIT.Kure: coVarCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoVar b -> Translate c m Coercion b
+ HERMIT.Kure: coercionR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m CoreExpr
+ HERMIT.Kure: coercionT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m CoreExpr b
+ HERMIT.Kure: consNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreProg a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreProg b
+ HERMIT.Kure: consRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreProg a3 -> ([(a1, a2)] -> a3 -> b) -> Translate c m CoreProg b
+ HERMIT.Kure: consRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: consRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreProg a2 -> ([a1] -> a2 -> b) -> Translate c m CoreProg b
+ HERMIT.Kure: defAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef
+ HERMIT.Kure: defAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef
+ HERMIT.Kure: defOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef
+ HERMIT.Kure: defOrNonRecAllR :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m g
+ HERMIT.Kure: defOrNonRecAnyR :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m g
+ HERMIT.Kure: defOrNonRecOneR :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m g
+ HERMIT.Kure: defOrNonRecT :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m g b
+ HERMIT.Kure: defT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Id a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreDef b
+ HERMIT.Kure: deprecatedIntToCrumbT :: Monad m => Int -> Translate c m Core Crumb
+ HERMIT.Kure: deprecatedIntToPathT :: Monad m => Int -> Translate c m Core LocalPathH
+ HERMIT.Kure: forAllCoAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: forAllCoAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: forAllCoOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: forAllCoT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m TyVar a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
+ HERMIT.Kure: forAllTyAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: forAllTyAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: forAllTyOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: forAllTyT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b
+ HERMIT.Kure: funTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: funTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: funTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type
+ HERMIT.Kure: funTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b
+ HERMIT.Kure: instCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: instCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: instCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: instCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
+ HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c Coercion
+ HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c Core
+ HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c CoreTC
+ HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c TyCo
+ HERMIT.Kure: instance (ExtendPath c Crumb, AddBindings c) => Walker c Type
+ HERMIT.Kure: lamAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: lamAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: lamOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: lamT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: letAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreExpr a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: letOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreExpr a3 -> ([(a1, a2)] -> a3 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: letRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: letRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreExpr a2 -> ([a1] -> a2 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: letT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: litR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Literal -> Rewrite c m CoreExpr
+ HERMIT.Kure: litT :: (ExtendPath c Crumb, Monad m) => Translate c m Literal b -> Translate c m CoreExpr b
+ HERMIT.Kure: litTyR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyLit -> Rewrite c m Type
+ HERMIT.Kure: litTyT :: (ExtendPath c Crumb, Monad m) => Translate c m TyLit b -> Translate c m Type b
+ HERMIT.Kure: modGutsR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreProg -> Rewrite c m ModGuts
+ HERMIT.Kure: modGutsT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreProg a -> (ModGuts -> a -> b) -> Translate c m ModGuts b
+ HERMIT.Kure: nonRecAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind
+ HERMIT.Kure: nonRecAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind
+ HERMIT.Kure: nonRecOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind
+ HERMIT.Kure: nonRecT :: (ExtendPath c Crumb, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreBind b
+ HERMIT.Kure: nthCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: nthCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: nthCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: nthCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Int a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
+ HERMIT.Kure: progConsAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: progConsAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: progConsOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg
+ HERMIT.Kure: progConsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreProg a2 -> (a1 -> a2 -> b) -> Translate c m CoreProg b
+ HERMIT.Kure: progNilT :: Monad m => b -> Translate c m CoreProg b
+ HERMIT.Kure: recAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind
+ HERMIT.Kure: recAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind
+ HERMIT.Kure: recDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind
+ HERMIT.Kure: recDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind
+ HERMIT.Kure: recDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind
+ HERMIT.Kure: recDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> ([(a1, a2)] -> b) -> Translate c m CoreBind b
+ HERMIT.Kure: recOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind
+ HERMIT.Kure: recT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a) -> ([a] -> b) -> Translate c m CoreBind b
+ HERMIT.Kure: reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: reflT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m Coercion b
+ HERMIT.Kure: symCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: symCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m Coercion b
+ HERMIT.Kure: tickAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: tickAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: tickOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr
+ HERMIT.Kure: tickT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreTickish a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b
+ HERMIT.Kure: transCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: transCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: transCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion
+ HERMIT.Kure: transCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
+ HERMIT.Kure: tyConAppAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type
+ HERMIT.Kure: tyConAppAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type
+ HERMIT.Kure: tyConAppCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
+ HERMIT.Kure: tyConAppCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
+ HERMIT.Kure: tyConAppCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion
+ HERMIT.Kure: tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b
+ HERMIT.Kure: tyConAppOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type
+ HERMIT.Kure: tyConAppT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m KindOrType a2) -> (a1 -> [a2] -> b) -> Translate c m Type b
+ HERMIT.Kure: tyVarR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyVar -> Rewrite c m Type
+ HERMIT.Kure: tyVarT :: (ExtendPath c Crumb, Monad m) => Translate c m TyVar b -> Translate c m Type b
+ HERMIT.Kure: type BiRewriteH a = BiRewrite HermitC HermitM a
+ HERMIT.Kure: type LensH a b = Lens HermitC HermitM a b
+ HERMIT.Kure: type PathH = Path Crumb
+ HERMIT.Kure: type RewriteH a = Rewrite HermitC HermitM a
+ HERMIT.Kure: type TranslateH a b = Translate HermitC HermitM a b
+ HERMIT.Kure: typeR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m CoreExpr
+ HERMIT.Kure: typeT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m CoreExpr b
+ HERMIT.Kure: unsafeCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: unsafeCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: unsafeCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion
+ HERMIT.Kure: unsafeCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b
+ HERMIT.Kure: varR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr
+ HERMIT.Kure: varT :: (ExtendPath c Crumb, Monad m) => Translate c m Id b -> Translate c m CoreExpr b
+ HERMIT.Kure.SumTypes: AltCore :: CoreAlt -> Core
+ HERMIT.Kure.SumTypes: BindCore :: CoreBind -> Core
+ HERMIT.Kure.SumTypes: CoercionCore :: Coercion -> TyCo
+ HERMIT.Kure.SumTypes: Core :: Core -> CoreTC
+ HERMIT.Kure.SumTypes: DefCore :: CoreDef -> Core
+ HERMIT.Kure.SumTypes: ExprCore :: CoreExpr -> Core
+ HERMIT.Kure.SumTypes: GutsCore :: ModGuts -> Core
+ HERMIT.Kure.SumTypes: ProgCore :: CoreProg -> Core
+ HERMIT.Kure.SumTypes: TyCo :: TyCo -> CoreTC
+ HERMIT.Kure.SumTypes: TypeCore :: Type -> TyCo
+ HERMIT.Kure.SumTypes: coreAlphaEq :: Core -> Core -> Bool
+ HERMIT.Kure.SumTypes: coreSyntaxEq :: Core -> Core -> Bool
+ HERMIT.Kure.SumTypes: coreTCAlphaEq :: CoreTC -> CoreTC -> Bool
+ HERMIT.Kure.SumTypes: coreTCSyntaxEq :: CoreTC -> CoreTC -> Bool
+ HERMIT.Kure.SumTypes: data Core
+ HERMIT.Kure.SumTypes: data CoreTC
+ HERMIT.Kure.SumTypes: data TyCo
+ HERMIT.Kure.SumTypes: freeVarsCore :: Core -> VarSet
+ HERMIT.Kure.SumTypes: freeVarsCoreTC :: CoreTC -> VarSet
+ HERMIT.Kure.SumTypes: freeVarsTyCo :: TyCo -> VarSet
+ HERMIT.Kure.SumTypes: instance Injection Coercion CoreTC
+ HERMIT.Kure.SumTypes: instance Injection Coercion TyCo
+ HERMIT.Kure.SumTypes: instance Injection Core CoreTC
+ HERMIT.Kure.SumTypes: instance Injection CoreAlt Core
+ HERMIT.Kure.SumTypes: instance Injection CoreAlt CoreTC
+ HERMIT.Kure.SumTypes: instance Injection CoreBind Core
+ HERMIT.Kure.SumTypes: instance Injection CoreBind CoreTC
+ HERMIT.Kure.SumTypes: instance Injection CoreDef Core
+ HERMIT.Kure.SumTypes: instance Injection CoreDef CoreTC
+ HERMIT.Kure.SumTypes: instance Injection CoreExpr Core
+ HERMIT.Kure.SumTypes: instance Injection CoreExpr CoreTC
+ HERMIT.Kure.SumTypes: instance Injection CoreProg Core
+ HERMIT.Kure.SumTypes: instance Injection CoreProg CoreTC
+ HERMIT.Kure.SumTypes: instance Injection ModGuts Core
+ HERMIT.Kure.SumTypes: instance Injection ModGuts CoreTC
+ HERMIT.Kure.SumTypes: instance Injection TyCo CoreTC
+ HERMIT.Kure.SumTypes: instance Injection Type CoreTC
+ HERMIT.Kure.SumTypes: instance Injection Type TyCo
+ HERMIT.Kure.SumTypes: promoteAltR :: (Monad m, Injection CoreAlt g) => Rewrite c m CoreAlt -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteAltT :: (Monad m, Injection CoreAlt g) => Translate c m CoreAlt b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteBindR :: (Monad m, Injection CoreBind g) => Rewrite c m CoreBind -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteBindT :: (Monad m, Injection CoreBind g) => Translate c m CoreBind b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteCoercionR :: (Monad m, Injection Coercion g) => Rewrite c m Coercion -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteCoercionT :: (Monad m, Injection Coercion g) => Translate c m Coercion b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteDefR :: (Monad m, Injection CoreDef g) => Rewrite c m CoreDef -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteDefT :: (Monad m, Injection CoreDef g) => Translate c m CoreDef b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteExprBiR :: (Monad m, Injection CoreExpr g) => BiRewrite c m CoreExpr -> BiRewrite c m g
+ HERMIT.Kure.SumTypes: promoteExprR :: (Monad m, Injection CoreExpr g) => Rewrite c m CoreExpr -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteExprT :: (Monad m, Injection CoreExpr g) => Translate c m CoreExpr b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteModGutsR :: (Monad m, Injection ModGuts g) => Rewrite c m ModGuts -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteModGutsT :: (Monad m, Injection ModGuts g) => Translate c m ModGuts b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteProgR :: (Monad m, Injection CoreProg g) => Rewrite c m CoreProg -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteProgT :: (Monad m, Injection CoreProg g) => Translate c m CoreProg b -> Translate c m g b
+ HERMIT.Kure.SumTypes: promoteTypeR :: (Monad m, Injection Type g) => Rewrite c m Type -> Rewrite c m g
+ HERMIT.Kure.SumTypes: promoteTypeT :: (Monad m, Injection Type g) => Translate c m Type b -> Translate c m g b
+ HERMIT.Kure.SumTypes: tyCoAlphaEq :: TyCo -> TyCo -> Bool
+ HERMIT.Kure.SumTypes: tyCoSyntaxEq :: TyCo -> TyCo -> Bool
+ HERMIT.Monad: DebugCore :: String -> HermitC -> CoreTC -> DebugMessage
+ HERMIT.Monad: DebugTick :: String -> DebugMessage
+ HERMIT.Monad: HermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv
+ HERMIT.Monad: cloneVarH :: (String -> String) -> Var -> HermitM Var
+ HERMIT.Monad: data DebugMessage
+ HERMIT.Monad: data HermitM a
+ HERMIT.Monad: getStash :: HermitM DefStash
+ HERMIT.Monad: hs_debugChan :: HermitMEnv -> DebugMessage -> HermitM ()
+ HERMIT.Monad: instance Applicative HermitM
+ HERMIT.Monad: instance Functor HermitM
+ HERMIT.Monad: instance HasDynFlags HermitM
+ HERMIT.Monad: instance Monad HermitM
+ HERMIT.Monad: instance MonadCatch HermitM
+ HERMIT.Monad: instance MonadIO HermitM
+ HERMIT.Monad: instance MonadThings HermitM
+ HERMIT.Monad: instance MonadUnique HermitM
+ HERMIT.Monad: liftCoreM :: CoreM a -> HermitM a
+ HERMIT.Monad: lookupDef :: Label -> HermitM CoreDef
+ HERMIT.Monad: mkHermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv
+ HERMIT.Monad: newCoVarH :: String -> Type -> HermitM TyVar
+ HERMIT.Monad: newGlobalIdH :: String -> Type -> HermitM Id
+ HERMIT.Monad: newIdH :: String -> Type -> HermitM Id
+ HERMIT.Monad: newTyVarH :: String -> Kind -> HermitM TyVar
+ HERMIT.Monad: newtype HermitMEnv
+ HERMIT.Monad: runHM :: HermitMEnv -> DefStash -> (DefStash -> a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b
+ HERMIT.Monad: saveDef :: Label -> CoreDef -> HermitM ()
+ HERMIT.Monad: sendDebugMessage :: DebugMessage -> HermitM ()
+ HERMIT.Monad: type DefStash = Map Label CoreDef
+ HERMIT.Monad: type Label = String
+ HERMIT.Optimize: after :: CorePass -> OM () -> OM ()
+ HERMIT.Optimize: allPhases :: OM () -> OM ()
+ HERMIT.Optimize: at :: TranslateH Core LocalPathH -> OM a -> OM a
+ HERMIT.Optimize: before :: CorePass -> OM () -> OM ()
+ HERMIT.Optimize: data OM a
+ HERMIT.Optimize: display :: OM ()
+ HERMIT.Optimize: firstPhase :: OM () -> OM ()
+ HERMIT.Optimize: instance Monad OM
+ HERMIT.Optimize: instance MonadIO OM
+ HERMIT.Optimize: interactive :: [External] -> [CommandLineOption] -> OM ()
+ HERMIT.Optimize: lastPhase :: OM () -> OM ()
+ HERMIT.Optimize: omToIO :: CommandLineState -> PhaseInfo -> OM a -> IO (Either CLException a, CommandLineState)
+ HERMIT.Optimize: optimize :: ([CommandLineOption] -> OM ()) -> Plugin
+ HERMIT.Optimize: phase :: Int -> OM () -> OM ()
+ HERMIT.Optimize: query :: (Injection ModGuts g, Walker HermitC g) => TranslateH g a -> OM a
+ HERMIT.Optimize: run :: RewriteH Core -> OM ()
+ HERMIT.Optimize: setPretty :: PrettyH CoreTC -> OM ()
+ HERMIT.Optimize: setPrettyOptions :: PrettyOptions -> OM ()
+ HERMIT.Parser: AppH :: ExprH -> ExprH -> ExprH
+ HERMIT.Parser: CmdName :: String -> ExprH
+ HERMIT.Parser: CoreH :: String -> ExprH
+ HERMIT.Parser: ListH :: [ExprH] -> ExprH
+ HERMIT.Parser: SrcName :: String -> ExprH
+ HERMIT.Parser: data ExprH
+ HERMIT.Parser: instance Eq ExprH
+ HERMIT.Parser: instance Eq Token
+ HERMIT.Parser: instance Show ExprH
+ HERMIT.Parser: instance Show Token
+ HERMIT.Parser: parseScript :: String -> Either String Script
+ HERMIT.Parser: type Script = [ExprH]
+ HERMIT.Parser: unparseExprH :: ExprH -> String
+ HERMIT.Parser: unparseScript :: Script -> String
+ HERMIT.ParserCore: instance Eq Token
+ HERMIT.ParserCore: instance Show Token
+ HERMIT.ParserCore: parse2beforeBiR :: (CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> BiRewriteH a
+ HERMIT.ParserCore: parse3beforeBiR :: (CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> CoreString -> BiRewriteH a
+ HERMIT.ParserCore: parseCore :: CoreString -> HermitC -> HermitM CoreExpr
+ HERMIT.ParserCore: parseCoreExprT :: CoreString -> TranslateH a CoreExpr
+ HERMIT.Plugin: CSE :: CorePass
+ HERMIT.Plugin: Desugar :: CorePass
+ HERMIT.Plugin: DesugarOpt :: CorePass
+ HERMIT.Plugin: FloatInwards :: CorePass
+ HERMIT.Plugin: FloatOutwards :: CorePass
+ HERMIT.Plugin: LiberateCase :: CorePass
+ HERMIT.Plugin: NoOp :: CorePass
+ HERMIT.Plugin: Passes :: CorePass
+ HERMIT.Plugin: PhaseInfo :: Int -> [CorePass] -> [CorePass] -> PhaseInfo
+ HERMIT.Plugin: PluginPass :: String -> CorePass
+ HERMIT.Plugin: Prep :: CorePass
+ HERMIT.Plugin: PrintCore :: CorePass
+ HERMIT.Plugin: RuleCheck :: CorePass
+ HERMIT.Plugin: Simplify :: CorePass
+ HERMIT.Plugin: SpecConstr :: CorePass
+ HERMIT.Plugin: Specialising :: CorePass
+ HERMIT.Plugin: StaticArgs :: CorePass
+ HERMIT.Plugin: Strictness :: CorePass
+ HERMIT.Plugin: Tidy :: CorePass
+ HERMIT.Plugin: Unknown :: CorePass
+ HERMIT.Plugin: Vectorisation :: CorePass
+ HERMIT.Plugin: WorkerWrapper :: CorePass
+ HERMIT.Plugin: data CorePass
+ HERMIT.Plugin: data PhaseInfo
+ HERMIT.Plugin: getCorePass :: CoreToDo -> CorePass
+ HERMIT.Plugin: ghcPasses :: [(CorePass, CoreToDo)]
+ HERMIT.Plugin: hermitPlugin :: HermitPass -> Plugin
+ HERMIT.Plugin: instance Eq CorePass
+ HERMIT.Plugin: instance Eq PhaseInfo
+ HERMIT.Plugin: instance Read CorePass
+ HERMIT.Plugin: instance Read PhaseInfo
+ HERMIT.Plugin: instance Show CorePass
+ HERMIT.Plugin: instance Show PhaseInfo
+ HERMIT.Plugin: phaseNum :: PhaseInfo -> Int
+ HERMIT.Plugin: phasesDone :: PhaseInfo -> [CorePass]
+ HERMIT.Plugin: phasesLeft :: PhaseInfo -> [CorePass]
+ HERMIT.Plugin: type HermitPass = PhaseInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts
+ HERMIT.PrettyPrinter.AST: ppCoercion :: PrettyH Coercion
+ HERMIT.PrettyPrinter.AST: ppCoreAlt :: PrettyH CoreAlt
+ HERMIT.PrettyPrinter.AST: ppCoreBind :: PrettyH CoreBind
+ HERMIT.PrettyPrinter.AST: ppCoreExpr :: PrettyH CoreExpr
+ HERMIT.PrettyPrinter.AST: ppCoreProg :: PrettyH CoreProg
+ HERMIT.PrettyPrinter.AST: ppCoreTC :: PrettyH CoreTC
+ HERMIT.PrettyPrinter.AST: ppKindOrType :: PrettyH Type
+ HERMIT.PrettyPrinter.AST: ppModGuts :: PrettyH ModGuts
+ HERMIT.PrettyPrinter.Clean: ppCoercion :: PrettyH Coercion
+ HERMIT.PrettyPrinter.Clean: ppCoreAlt :: PrettyH CoreAlt
+ HERMIT.PrettyPrinter.Clean: ppCoreBind :: PrettyH CoreBind
+ HERMIT.PrettyPrinter.Clean: ppCoreExpr :: PrettyH CoreExpr
+ HERMIT.PrettyPrinter.Clean: ppCoreProg :: PrettyH CoreProg
+ HERMIT.PrettyPrinter.Clean: ppCoreTC :: PrettyH CoreTC
+ HERMIT.PrettyPrinter.Clean: ppKindOrType :: PrettyH KindOrType
+ HERMIT.PrettyPrinter.Clean: ppModGuts :: PrettyH ModGuts
+ HERMIT.PrettyPrinter.Common: Abstract :: ShowOption
+ HERMIT.PrettyPrinter.Common: CastSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: CoercionBindSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: CoercionColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: CoercionSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: Color :: SyntaxForColor -> Attr
+ HERMIT.PrettyPrinter.Common: ForallSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: HTML :: String -> HTML
+ HERMIT.PrettyPrinter.Common: IdColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: KeywordColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: Kind :: ShowOption
+ HERMIT.PrettyPrinter.Common: LambdaSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: LitColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: Omit :: ShowOption
+ HERMIT.PrettyPrinter.Common: PathAttr :: AbsolutePathH -> Attr
+ HERMIT.PrettyPrinter.Common: PrettyC :: AbsolutePath Crumb -> VarSet -> PrettyOptions -> PrettyC
+ HERMIT.PrettyPrinter.Common: PrettyOptions :: Bool -> ShowOption -> ShowOption -> ShowOption -> Maybe PathH -> Maybe Int -> Bool -> Float -> Int -> PrettyOptions
+ HERMIT.PrettyPrinter.Common: RightArrowSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: Show :: ShowOption
+ HERMIT.PrettyPrinter.Common: SpecialFont :: Attr
+ HERMIT.PrettyPrinter.Common: SyntaxColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: TranslateCoreTCDocHBox :: (TranslateDocH CoreTC) -> TranslateCoreTCDocHBox
+ HERMIT.PrettyPrinter.Common: TranslateDocH :: (PrettyC -> PrettyH a -> TranslateH a DocH) -> TranslateDocH a
+ HERMIT.PrettyPrinter.Common: TypeBindSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: TypeColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: TypeOfSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: TypeSymbol :: SpecialSymbol
+ HERMIT.PrettyPrinter.Common: Unicode :: Char -> Unicode
+ HERMIT.PrettyPrinter.Common: WarningColor :: SyntaxForColor
+ HERMIT.PrettyPrinter.Common: attrP :: AbsolutePathH -> DocH -> DocH
+ HERMIT.PrettyPrinter.Common: class (RenderSpecial a, Monoid a) => RenderCode a where rStart = mempty rEnd = mempty
+ HERMIT.PrettyPrinter.Common: class RenderSpecial a
+ HERMIT.PrettyPrinter.Common: coercionColor :: DocH -> DocH
+ HERMIT.PrettyPrinter.Common: coreRenders :: [(String, PrettyOptions -> DocH -> String)]
+ HERMIT.PrettyPrinter.Common: data Attr
+ HERMIT.PrettyPrinter.Common: data PrettyC
+ HERMIT.PrettyPrinter.Common: data PrettyOptions
+ HERMIT.PrettyPrinter.Common: data ShowOption
+ HERMIT.PrettyPrinter.Common: data SpecialSymbol
+ HERMIT.PrettyPrinter.Common: data SyntaxForColor
+ HERMIT.PrettyPrinter.Common: data TranslateCoreTCDocHBox
+ HERMIT.PrettyPrinter.Common: hlist :: [MDoc a] -> MDoc a
+ HERMIT.PrettyPrinter.Common: idColor :: DocH -> DocH
+ HERMIT.PrettyPrinter.Common: initPrettyC :: PrettyOptions -> PrettyC
+ HERMIT.PrettyPrinter.Common: instance AddBindings PrettyC
+ HERMIT.PrettyPrinter.Common: instance BoundVars PrettyC
+ HERMIT.PrettyPrinter.Common: instance Bounded SpecialSymbol
+ HERMIT.PrettyPrinter.Common: instance Default PrettyOptions
+ HERMIT.PrettyPrinter.Common: instance Enum SpecialSymbol
+ HERMIT.PrettyPrinter.Common: instance Eq Attr
+ HERMIT.PrettyPrinter.Common: instance Eq ShowOption
+ HERMIT.PrettyPrinter.Common: instance Eq SpecialSymbol
+ HERMIT.PrettyPrinter.Common: instance Eq SyntaxForColor
+ HERMIT.PrettyPrinter.Common: instance ExtendPath PrettyC Crumb
+ HERMIT.PrettyPrinter.Common: instance Extern (TranslateDocH CoreTC)
+ HERMIT.PrettyPrinter.Common: instance Monoid ASCII
+ HERMIT.PrettyPrinter.Common: instance Monoid DebugPretty
+ HERMIT.PrettyPrinter.Common: instance Monoid HTML
+ HERMIT.PrettyPrinter.Common: instance Monoid LaTeX
+ HERMIT.PrettyPrinter.Common: instance Ord ShowOption
+ HERMIT.PrettyPrinter.Common: instance Ord SpecialSymbol
+ HERMIT.PrettyPrinter.Common: instance Read ShowOption
+ HERMIT.PrettyPrinter.Common: instance ReadPath PrettyC Crumb
+ HERMIT.PrettyPrinter.Common: instance RenderCode ASCII
+ HERMIT.PrettyPrinter.Common: instance RenderCode DebugPretty
+ HERMIT.PrettyPrinter.Common: instance RenderCode HTML
+ HERMIT.PrettyPrinter.Common: instance RenderCode LaTeX
+ HERMIT.PrettyPrinter.Common: instance RenderSpecial ASCII
+ HERMIT.PrettyPrinter.Common: instance RenderSpecial Char
+ HERMIT.PrettyPrinter.Common: instance RenderSpecial DebugPretty
+ HERMIT.PrettyPrinter.Common: instance RenderSpecial HTML
+ HERMIT.PrettyPrinter.Common: instance RenderSpecial LaTeX
+ HERMIT.PrettyPrinter.Common: instance RenderSpecial Unicode
+ HERMIT.PrettyPrinter.Common: instance Show Attr
+ HERMIT.PrettyPrinter.Common: instance Show HermitMark
+ HERMIT.PrettyPrinter.Common: instance Show PrettyOptions
+ HERMIT.PrettyPrinter.Common: instance Show ShowOption
+ HERMIT.PrettyPrinter.Common: instance Show SpecialSymbol
+ HERMIT.PrettyPrinter.Common: instance Show SyntaxForColor
+ HERMIT.PrettyPrinter.Common: instance Typeable TranslateCoreTCDocHBox
+ HERMIT.PrettyPrinter.Common: keywordColor :: DocH -> DocH
+ HERMIT.PrettyPrinter.Common: liftPrettyC :: (ReadBindings c, ReadPath c Crumb) => PrettyOptions -> c -> PrettyC
+ HERMIT.PrettyPrinter.Common: liftPrettyH :: (ReadBindings c, ReadPath c Crumb) => PrettyOptions -> PrettyH a -> Translate c HermitM a DocH
+ HERMIT.PrettyPrinter.Common: markColor :: SyntaxForColor -> DocH -> DocH
+ HERMIT.PrettyPrinter.Common: newtype HTML
+ HERMIT.PrettyPrinter.Common: newtype TranslateDocH a
+ HERMIT.PrettyPrinter.Common: newtype Unicode
+ HERMIT.PrettyPrinter.Common: po_coercions :: PrettyOptions -> ShowOption
+ HERMIT.PrettyPrinter.Common: po_depth :: PrettyOptions -> Maybe Int
+ HERMIT.PrettyPrinter.Common: po_exprTypes :: PrettyOptions -> ShowOption
+ HERMIT.PrettyPrinter.Common: po_focus :: PrettyOptions -> Maybe PathH
+ HERMIT.PrettyPrinter.Common: po_fullyQualified :: PrettyOptions -> Bool
+ HERMIT.PrettyPrinter.Common: po_notes :: PrettyOptions -> Bool
+ HERMIT.PrettyPrinter.Common: po_ribbon :: PrettyOptions -> Float
+ HERMIT.PrettyPrinter.Common: po_typesForBinders :: PrettyOptions -> ShowOption
+ HERMIT.PrettyPrinter.Common: po_width :: PrettyOptions -> Int
+ HERMIT.PrettyPrinter.Common: prettyC_options :: PrettyC -> PrettyOptions
+ HERMIT.PrettyPrinter.Common: prettyC_path :: PrettyC -> AbsolutePath Crumb
+ HERMIT.PrettyPrinter.Common: prettyC_vars :: PrettyC -> VarSet
+ HERMIT.PrettyPrinter.Common: rDoHighlight :: RenderCode a => Maybe Attr -> [Attr] -> a
+ HERMIT.PrettyPrinter.Common: rEnd :: RenderCode a => a
+ HERMIT.PrettyPrinter.Common: rPutStr :: RenderCode a => String -> a
+ HERMIT.PrettyPrinter.Common: rStart :: RenderCode a => a
+ HERMIT.PrettyPrinter.Common: renderCode :: RenderCode a => PrettyOptions -> DocH -> a
+ HERMIT.PrettyPrinter.Common: renderSpecial :: RenderSpecial a => SpecialSymbol -> a
+ HERMIT.PrettyPrinter.Common: specialFont :: DocH -> DocH
+ HERMIT.PrettyPrinter.Common: type DocH = MDoc HermitMark
+ HERMIT.PrettyPrinter.Common: type PrettyH a = Translate PrettyC HermitM a DocH
+ HERMIT.PrettyPrinter.Common: typeColor :: DocH -> DocH
+ HERMIT.PrettyPrinter.Common: unTranslateDocH :: TranslateDocH a -> PrettyC -> PrettyH a -> TranslateH a DocH
+ HERMIT.PrettyPrinter.Common: updateCoShowOption :: ShowOption -> PrettyOptions -> PrettyOptions
+ HERMIT.PrettyPrinter.Common: updateTypeShowOption :: ShowOption -> PrettyOptions -> PrettyOptions
+ HERMIT.PrettyPrinter.Common: updateWidthOption :: Int -> PrettyOptions -> PrettyOptions
+ HERMIT.PrettyPrinter.Common: vlist :: [MDoc a] -> MDoc a
+ HERMIT.PrettyPrinter.GHC: ppCoercion :: PrettyH Coercion
+ HERMIT.PrettyPrinter.GHC: ppCoreAlt :: PrettyH CoreAlt
+ HERMIT.PrettyPrinter.GHC: ppCoreBind :: PrettyH CoreBind
+ HERMIT.PrettyPrinter.GHC: ppCoreExpr :: PrettyH CoreExpr
+ HERMIT.PrettyPrinter.GHC: ppCoreProg :: PrettyH CoreProg
+ HERMIT.PrettyPrinter.GHC: ppCoreTC :: PrettyH CoreTC
+ HERMIT.PrettyPrinter.GHC: ppKindOrType :: PrettyH Type
+ HERMIT.PrettyPrinter.GHC: ppModGuts :: PrettyH ModGuts
+ HERMIT.Shell.Command: cl_kernel_env :: CommandLineState -> HermitMEnv
+ HERMIT.Shell.Command: commandLine :: MonadIO m => [CommandLineOption] -> Behavior -> [External] -> CLM m ()
+ HERMIT.Shell.Command: diffDocH :: (MonadCatch m, MonadIO m) => PrettyOptions -> DocH -> DocH -> m String
+ HERMIT.Shell.Command: diffR :: Injection a CoreTC => PrettyOptions -> String -> RewriteH a -> RewriteH a
+ HERMIT.Shell.Command: evalScript :: MonadIO m => String -> CLM m ()
+ HERMIT.Shell.Command: getFocusPath :: MonadIO m => CLM m PathH
+ HERMIT.Shell.Command: instance Show CompletionType
+ HERMIT.Shell.Command: performKernelEffect :: MonadIO m => KernelEffect -> ExprH -> CLM m ()
+ HERMIT.Shell.Command: performMetaCommand :: MonadIO m => MetaCommand -> CLM m ()
+ HERMIT.Shell.Command: performQuery :: MonadIO m => QueryFun -> CLM m ()
+ HERMIT.Shell.Command: performShellEffect :: MonadIO m => ShellEffect -> CLM m ()
+ HERMIT.Shell.Command: shellComplete :: MVar CommandLineState -> String -> String -> IO [Completion]
+ HERMIT.Shell.Command: unicodeConsole :: Handle -> PrettyOptions -> Either String DocH -> IO ()
+ HERMIT.Shell.Dictionary: mkDict :: [External] -> Dictionary
+ HERMIT.Shell.Dictionary: pp_dictionary :: Map String (PrettyH CoreTC)
+ HERMIT.Shell.Externals: displayScripts :: QueryFun
+ HERMIT.Shell.Externals: gc :: CommandLineState -> IO CommandLineState
+ HERMIT.Shell.Externals: interpShellCommand :: [Interp ShellCommand]
+ HERMIT.Shell.Externals: setWindow :: CommandLineState -> IO CommandLineState
+ HERMIT.Shell.Externals: shell_externals :: [External]
+ HERMIT.Shell.Externals: showDerivationTree :: CommandLineState -> IO String
+ HERMIT.Shell.Externals: showGraph :: [(SAST, ExprH, SAST)] -> [(String, SAST)] -> SAST -> String
+ HERMIT.Shell.Externals: showRefactorTrail :: (Eq a, Show a) => [(a, [String], a)] -> [(a, String)] -> a -> a -> [String]
+ HERMIT.Shell.Externals: showScripts :: [(ScriptName, Script)] -> String
+ HERMIT.Shell.Externals: versionCmd :: VersionCmd -> CommandLineState -> IO CommandLineState
+ HERMIT.Shell.Renderer: UnicodeTerminal :: (Handle -> Maybe PathH -> IO ()) -> UnicodeTerminal
+ HERMIT.Shell.Renderer: changeRenderer :: String -> ShellEffect
+ HERMIT.Shell.Renderer: doSGR :: [SGR] -> UnicodeTerminal
+ HERMIT.Shell.Renderer: instance Monoid UnicodeTerminal
+ HERMIT.Shell.Renderer: instance RenderCode UnicodeTerminal
+ HERMIT.Shell.Renderer: instance RenderSpecial UnicodeTerminal
+ HERMIT.Shell.Renderer: newtype UnicodeTerminal
+ HERMIT.Shell.Renderer: setHighlight :: PathH -> Handle -> Maybe PathH -> IO ()
+ HERMIT.Shell.Renderer: shellRenderers :: [(String, Handle -> PrettyOptions -> Either String DocH -> IO ())]
+ HERMIT.Shell.Renderer: showRenderers :: QueryFun
+ HERMIT.Shell.Renderer: undoSGRWith :: [SGR] -> [Attr] -> UnicodeTerminal
+ HERMIT.Shell.Renderer: unicodeConsole :: Handle -> PrettyOptions -> Either String DocH -> IO ()
+ HERMIT.Shell.ScriptToRewrite: addScriptToDict :: Monad m => ScriptName -> Script -> Dictionary -> m Dictionary
+ HERMIT.Shell.Types: Abort :: MetaCommand
+ HERMIT.Shell.Types: AddTag :: String -> VersionCmd
+ HERMIT.Shell.Types: Apply :: RewriteH g -> KernelEffect
+ HERMIT.Shell.Types: Back :: VersionCmd
+ HERMIT.Shell.Types: BeginScope :: KernelEffect
+ HERMIT.Shell.Types: CLAbort :: CLException
+ HERMIT.Shell.Types: CLContinue :: CommandLineState -> CLException
+ HERMIT.Shell.Types: CLError :: String -> CLException
+ HERMIT.Shell.Types: CLM :: ErrorT CLException (StateT CommandLineState m) a -> CLM m a
+ HERMIT.Shell.Types: CLResume :: SAST -> CLException
+ HERMIT.Shell.Types: CLSModify :: (CommandLineState -> IO CommandLineState) -> ShellEffect
+ HERMIT.Shell.Types: CommandLineState :: SAST -> PrettyH CoreTC -> PrettyOptions -> (Handle -> PrettyOptions -> Either String DocH -> IO ()) -> Int -> Bool -> Bool -> TVar (Map String Int) -> Bool -> Bool -> PathH -> Dictionary -> [(ScriptName, Script)] -> ScopedKernel -> SAST -> VersionStore -> CommandLineState
+ HERMIT.Shell.Types: Continue :: MetaCommand
+ HERMIT.Shell.Types: CorrectnessCritera :: TranslateH g () -> KernelEffect
+ HERMIT.Shell.Types: DefineScript :: ScriptName -> String -> MetaCommand
+ HERMIT.Shell.Types: Delete :: SAST -> KernelEffect
+ HERMIT.Shell.Types: Diff :: SAST -> SAST -> MetaCommand
+ HERMIT.Shell.Types: Direction :: Direction -> KernelEffect
+ HERMIT.Shell.Types: Display :: QueryFun
+ HERMIT.Shell.Types: Dump :: String -> String -> Int -> MetaCommand
+ HERMIT.Shell.Types: EndScope :: KernelEffect
+ HERMIT.Shell.Types: Goto :: Int -> VersionCmd
+ HERMIT.Shell.Types: GotoTag :: String -> VersionCmd
+ HERMIT.Shell.Types: Inquiry :: (CommandLineState -> IO String) -> QueryFun
+ HERMIT.Shell.Types: KernelEffect :: KernelEffect -> ShellCommand
+ HERMIT.Shell.Types: LoadFile :: ScriptName -> FilePath -> MetaCommand
+ HERMIT.Shell.Types: MetaCommand :: MetaCommand -> ShellCommand
+ HERMIT.Shell.Types: Pathfinder :: TranslateH g LocalPathH -> KernelEffect
+ HERMIT.Shell.Types: QueryDocH :: (PrettyC -> PrettyH CoreTC -> TranslateH CoreTC DocH) -> QueryFun
+ HERMIT.Shell.Types: QueryFun :: QueryFun -> ShellCommand
+ HERMIT.Shell.Types: QueryString :: TranslateH g String -> QueryFun
+ HERMIT.Shell.Types: Resume :: MetaCommand
+ HERMIT.Shell.Types: RunScript :: ScriptName -> MetaCommand
+ HERMIT.Shell.Types: SaveFile :: FilePath -> MetaCommand
+ HERMIT.Shell.Types: SaveScript :: FilePath -> ScriptName -> MetaCommand
+ HERMIT.Shell.Types: ScriptToRewrite :: RewriteName -> ScriptName -> MetaCommand
+ HERMIT.Shell.Types: SeqMeta :: [MetaCommand] -> MetaCommand
+ HERMIT.Shell.Types: ShellEffect :: ShellEffect -> ShellCommand
+ HERMIT.Shell.Types: Step :: VersionCmd
+ HERMIT.Shell.Types: VersionStore :: [(SAST, ExprH, SAST)] -> [(String, SAST)] -> VersionStore
+ HERMIT.Shell.Types: abort :: Monad m => CLM m ()
+ HERMIT.Shell.Types: cl_corelint :: CommandLineState -> Bool
+ HERMIT.Shell.Types: cl_cursor :: CommandLineState -> SAST
+ HERMIT.Shell.Types: cl_dict :: CommandLineState -> Dictionary
+ HERMIT.Shell.Types: cl_failhard :: CommandLineState -> Bool
+ HERMIT.Shell.Types: cl_height :: CommandLineState -> Int
+ HERMIT.Shell.Types: cl_initSAST :: CommandLineState -> SAST
+ HERMIT.Shell.Types: cl_kernel :: CommandLineState -> ScopedKernel
+ HERMIT.Shell.Types: cl_nav :: CommandLineState -> Bool
+ HERMIT.Shell.Types: cl_pretty :: CommandLineState -> PrettyH CoreTC
+ HERMIT.Shell.Types: cl_pretty_opts :: CommandLineState -> PrettyOptions
+ HERMIT.Shell.Types: cl_render :: CommandLineState -> Handle -> PrettyOptions -> Either String DocH -> IO ()
+ HERMIT.Shell.Types: cl_running_script :: CommandLineState -> Bool
+ HERMIT.Shell.Types: cl_scripts :: CommandLineState -> [(ScriptName, Script)]
+ HERMIT.Shell.Types: cl_tick :: CommandLineState -> TVar (Map String Int)
+ HERMIT.Shell.Types: cl_version :: CommandLineState -> VersionStore
+ HERMIT.Shell.Types: cl_window :: CommandLineState -> PathH
+ HERMIT.Shell.Types: continue :: Monad m => CommandLineState -> CLM m ()
+ HERMIT.Shell.Types: data CLException
+ HERMIT.Shell.Types: data CommandLineState
+ HERMIT.Shell.Types: data KernelEffect :: *
+ HERMIT.Shell.Types: data MetaCommand
+ HERMIT.Shell.Types: data QueryFun :: *
+ HERMIT.Shell.Types: data ShellCommand
+ HERMIT.Shell.Types: data ShellEffect :: *
+ HERMIT.Shell.Types: data VersionCmd
+ HERMIT.Shell.Types: data VersionStore
+ HERMIT.Shell.Types: instance Error CLException
+ HERMIT.Shell.Types: instance Extern KernelEffect
+ HERMIT.Shell.Types: instance Extern MetaCommand
+ HERMIT.Shell.Types: instance Extern QueryFun
+ HERMIT.Shell.Types: instance Extern ShellEffect
+ HERMIT.Shell.Types: instance Monad m => Monad (CLM m)
+ HERMIT.Shell.Types: instance Monad m => MonadCatch (CLM m)
+ HERMIT.Shell.Types: instance Monad m => MonadError CLException (CLM m)
+ HERMIT.Shell.Types: instance Monad m => MonadState CommandLineState (CLM m)
+ HERMIT.Shell.Types: instance MonadIO m => MonadIO (CLM m)
+ HERMIT.Shell.Types: instance MonadTrans CLM
+ HERMIT.Shell.Types: instance Show VersionCmd
+ HERMIT.Shell.Types: instance Typeable KernelEffect
+ HERMIT.Shell.Types: instance Typeable MetaCommand
+ HERMIT.Shell.Types: instance Typeable QueryFun
+ HERMIT.Shell.Types: instance Typeable ShellEffect
+ HERMIT.Shell.Types: iokm2clm :: MonadIO m => String -> IO (KureM a) -> CLM m a
+ HERMIT.Shell.Types: iokm2clm' :: MonadIO m => String -> (a -> CLM m b) -> IO (KureM a) -> CLM m b
+ HERMIT.Shell.Types: iokm2clm'' :: MonadIO m => IO (KureM a) -> CLM m a
+ HERMIT.Shell.Types: loadAndRun :: FilePath -> MetaCommand
+ HERMIT.Shell.Types: message :: String -> QueryFun
+ HERMIT.Shell.Types: newSAST :: ExprH -> SAST -> CommandLineState -> CommandLineState
+ HERMIT.Shell.Types: newtype CLM m a
+ HERMIT.Shell.Types: resume :: Monad m => SAST -> CLM m ()
+ HERMIT.Shell.Types: runCLM :: CommandLineState -> CLM m a -> m (Either CLException a, CommandLineState)
+ HERMIT.Shell.Types: type RewriteName = String
+ HERMIT.Shell.Types: type ScriptName = String
+ HERMIT.Shell.Types: unCLM :: CLM m a -> ErrorT CLException (StateT CommandLineState m) a
+ HERMIT.Shell.Types: vs_graph :: VersionStore -> [(SAST, ExprH, SAST)]
+ HERMIT.Shell.Types: vs_tags :: VersionStore -> [(String, SAST)]

Files

+ dist/build/HERMIT/Parser.hs view
@@ -0,0 +1,752 @@+{-# OPTIONS_GHC -w #-}+{-# OPTIONS -fglasgow-exts -cpp #-}+module HERMIT.Parser+    ( Script+    , parseScript+    , unparseScript+    , unparseExprH+    , ExprH(..)+    ) where++import Data.Char (isSpace)+import Data.List (intercalate)++import Control.Monad ((>=>))++import HERMIT.Syntax (isScriptInfixIdChar, isScriptIdFirstChar, isScriptIdChar)+import qualified Data.Array as Happy_Data_Array+import qualified GHC.Exts as Happy_GHC_Exts++-- parser produced by Happy Version 1.19.0++newtype HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 = HappyAbsSyn HappyAny+#if __GLASGOW_HASKELL__ >= 607+type HappyAny = Happy_GHC_Exts.Any+#else+type HappyAny = forall a . a+#endif+happyIn4 :: t4 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn4 #-}+happyOut4 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t4+happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut4 #-}+happyIn5 :: t5 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn5 #-}+happyOut5 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t5+happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut5 #-}+happyIn6 :: t6 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn6 #-}+happyOut6 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t6+happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut6 #-}+happyIn7 :: t7 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn7 #-}+happyOut7 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t7+happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut7 #-}+happyIn8 :: t8 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn8 #-}+happyOut8 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t8+happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut8 #-}+happyIn9 :: t9 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn9 #-}+happyOut9 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t9+happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut9 #-}+happyIn10 :: t10 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn10 #-}+happyOut10 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t10+happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut10 #-}+happyIn11 :: t11 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn11 #-}+happyOut11 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t11+happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut11 #-}+happyInTok :: (Token) -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)+happyInTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyInTok #-}+happyOutTok :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> (Token)+happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOutTok #-}+++happyActOffsets :: HappyAddr+happyActOffsets = HappyA# "\x0e\x00\x1e\x00\x0e\x00\x06\x00\x00\x00\x00\x00\xfd\xff\x01\x00\x00\x00\x1a\x00\x0e\x00\x1a\x00\x0e\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x09\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00"#++happyGotoOffsets :: HappyAddr+happyGotoOffsets = HappyA# "\x45\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00\x4d\x00\x39\x00\x48\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x2d\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00"#++happyDefActions :: HappyAddr+happyDefActions = HappyA# "\xfa\xff\x00\x00\xfa\xff\x00\x00\xfc\xff\xfb\xff\xf9\xff\xf4\xff\xf2\xff\x00\x00\xfa\xff\xe8\xff\xfa\xff\x00\x00\xed\xff\xee\xff\xea\xff\xef\xff\xf1\xff\xf0\xff\xf6\xff\xe7\xff\x00\x00\xe9\xff\xfd\xff\x00\x00\xf3\xff\x00\x00\xfa\xff\xfa\xff\xfe\xff\xf7\xff\xf8\xff\xf5\xff\xeb\xff\xec\xff\x00\x00\xe6\xff"#++happyCheck :: HappyAddr+happyCheck = HappyA# "\xff\xff\x04\x00\x01\x00\x05\x00\x02\x00\x08\x00\x05\x00\x03\x00\x04\x00\x05\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x01\x00\x07\x00\x03\x00\x04\x00\x05\x00\x0e\x00\x06\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x01\x00\x03\x00\x04\x00\x05\x00\x05\x00\x07\x00\x03\x00\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x03\x00\x04\x00\x05\x00\xff\xff\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++happyTable :: HappyAddr+happyTable = HappyA# "\x00\x00\x1d\x00\x0a\x00\x1a\x00\x23\x00\x1e\x00\x0c\x00\x21\x00\x07\x00\x08\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1c\x00\x0a\x00\x24\x00\x03\x00\x0b\x00\x0c\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x0a\x00\x15\x00\x07\x00\x08\x00\x0c\x00\x25\x00\x03\x00\x00\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1f\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x20\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x14\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x18\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x1e\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x15\x00\x07\x00\x08\x00\x16\x00\x17\x00\x19\x00\x07\x00\x08\x00\x00\x00\x12\x00\x13\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++happyReduceArr = Happy_Data_Array.array (1, 25) [+	(1 , happyReduce_1),+	(2 , happyReduce_2),+	(3 , happyReduce_3),+	(4 , happyReduce_4),+	(5 , happyReduce_5),+	(6 , happyReduce_6),+	(7 , happyReduce_7),+	(8 , happyReduce_8),+	(9 , happyReduce_9),+	(10 , happyReduce_10),+	(11 , happyReduce_11),+	(12 , happyReduce_12),+	(13 , happyReduce_13),+	(14 , happyReduce_14),+	(15 , happyReduce_15),+	(16 , happyReduce_16),+	(17 , happyReduce_17),+	(18 , happyReduce_18),+	(19 , happyReduce_19),+	(20 , happyReduce_20),+	(21 , happyReduce_21),+	(22 , happyReduce_22),+	(23 , happyReduce_23),+	(24 , happyReduce_24),+	(25 , happyReduce_25)+	]++happy_n_terms = 15 :: Int+happy_n_nonterms = 8 :: Int++happyReduce_1 = happySpecReduce_2  0# happyReduction_1+happyReduction_1 happy_x_2+	happy_x_1+	 =  case happyOut4 happy_x_2 of { happy_var_2 -> +	happyIn4+		 (CmdName "{" : happy_var_2+	)}++happyReduce_2 = happySpecReduce_2  0# happyReduction_2+happyReduction_2 happy_x_2+	happy_x_1+	 =  case happyOut4 happy_x_2 of { happy_var_2 -> +	happyIn4+		 (CmdName "}" : happy_var_2+	)}++happyReduce_3 = happySpecReduce_1  0# happyReduction_3+happyReduction_3 happy_x_1+	 =  case happyOut5 happy_x_1 of { happy_var_1 -> +	happyIn4+		 (happy_var_1+	)}++happyReduce_4 = happySpecReduce_1  1# happyReduction_4+happyReduction_4 happy_x_1+	 =  case happyOut6 happy_x_1 of { happy_var_1 -> +	happyIn5+		 (happy_var_1+	)}++happyReduce_5 = happySpecReduce_0  1# happyReduction_5+happyReduction_5  =  happyIn5+		 ([]+	)++happyReduce_6 = happySpecReduce_1  2# happyReduction_6+happyReduction_6 happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	happyIn6+		 ([happy_var_1]+	)}++happyReduce_7 = happySpecReduce_3  2# happyReduction_7+happyReduction_7 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	case happyOut4 happy_x_3 of { happy_var_3 -> +	happyIn6+		 ([happy_var_1, CmdName "}"] ++ happy_var_3+	)}}++happyReduce_8 = happySpecReduce_3  2# happyReduction_8+happyReduction_8 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	case happyOut4 happy_x_3 of { happy_var_3 -> +	happyIn6+		 (happy_var_1 : happy_var_3+	)}}++happyReduce_9 = happySpecReduce_2  2# happyReduction_9+happyReduction_9 happy_x_2+	happy_x_1+	 =  case happyOut4 happy_x_2 of { happy_var_2 -> +	happyIn6+		 (happy_var_2+	)}++happyReduce_10 = happySpecReduce_3  3# happyReduction_10+happyReduction_10 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	case happyOutTok happy_x_2 of { (InfixOp happy_var_2) -> +	case happyOut7 happy_x_3 of { happy_var_3 -> +	happyIn7+		 (AppH (AppH (CmdName happy_var_2) happy_var_1) happy_var_3+	)}}}++happyReduce_11 = happySpecReduce_1  3# happyReduction_11+happyReduction_11 happy_x_1+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	happyIn7+		 (happy_var_1+	)}++happyReduce_12 = happySpecReduce_2  4# happyReduction_12+happyReduction_12 happy_x_2+	happy_x_1+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	case happyOut9 happy_x_2 of { happy_var_2 -> +	happyIn8+		 (AppH happy_var_1 happy_var_2+	)}}++happyReduce_13 = happySpecReduce_1  4# happyReduction_13+happyReduction_13 happy_x_1+	 =  case happyOut9 happy_x_1 of { happy_var_1 -> +	happyIn8+		 (happy_var_1+	)}++happyReduce_14 = happySpecReduce_2  5# happyReduction_14+happyReduction_14 happy_x_2+	happy_x_1+	 =  case happyOutTok happy_x_2 of { (Ident happy_var_2) -> +	happyIn9+		 (SrcName happy_var_2+	)}++happyReduce_15 = happySpecReduce_2  5# happyReduction_15+happyReduction_15 happy_x_2+	happy_x_1+	 =  case happyOutTok happy_x_2 of { (InfixOp happy_var_2) -> +	happyIn9+		 (SrcName happy_var_2+	)}++happyReduce_16 = happySpecReduce_2  5# happyReduction_16+happyReduction_16 happy_x_2+	happy_x_1+	 =  case happyOutTok happy_x_2 of { (Quote happy_var_2) -> +	happyIn9+		 (SrcName happy_var_2+	)}++happyReduce_17 = happySpecReduce_1  5# happyReduction_17+happyReduction_17 happy_x_1+	 =  case happyOutTok happy_x_1 of { (Quote happy_var_1) -> +	happyIn9+		 (CmdName happy_var_1+	)}++happyReduce_18 = happySpecReduce_1  5# happyReduction_18+happyReduction_18 happy_x_1+	 =  case happyOutTok happy_x_1 of { (CoreString happy_var_1) -> +	happyIn9+		 (CoreH happy_var_1+	)}++happyReduce_19 = happySpecReduce_3  5# happyReduction_19+happyReduction_19 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut10 happy_x_2 of { happy_var_2 -> +	happyIn9+		 (ListH happy_var_2+	)}++happyReduce_20 = happySpecReduce_3  5# happyReduction_20+happyReduction_20 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut7 happy_x_2 of { happy_var_2 -> +	happyIn9+		 (happy_var_2+	)}++happyReduce_21 = happySpecReduce_1  5# happyReduction_21+happyReduction_21 happy_x_1+	 =  case happyOutTok happy_x_1 of { (Ident happy_var_1) -> +	happyIn9+		 (CmdName happy_var_1+	)}++happyReduce_22 = happySpecReduce_1  6# happyReduction_22+happyReduction_22 happy_x_1+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> +	happyIn10+		 (happy_var_1+	)}++happyReduce_23 = happySpecReduce_0  6# happyReduction_23+happyReduction_23  =  happyIn10+		 ([]+	)++happyReduce_24 = happySpecReduce_1  7# happyReduction_24+happyReduction_24 happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	happyIn11+		 ([happy_var_1]+	)}++happyReduce_25 = happySpecReduce_3  7# happyReduction_25+happyReduction_25 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	case happyOut11 happy_x_3 of { happy_var_3 -> +	happyIn11+		 (happy_var_1 : happy_var_3+	)}}++happyNewToken action sts stk [] =+	happyDoAction 14# notHappyAtAll action sts stk []++happyNewToken action sts stk (tk:tks) =+	let cont i = happyDoAction i tk action sts stk tks in+	case tk of {+	ParenLeft -> cont 1#;+	ParenRight -> cont 2#;+	ScopeStart -> cont 3#;+	ScopeEnd -> cont 4#;+	ListStart -> cont 5#;+	ListDelim -> cont 6#;+	ListEnd -> cont 7#;+	StmtEnd -> cont 8#;+	Tick -> cont 9#;+	CoreString happy_dollar_dollar -> cont 10#;+	Quote happy_dollar_dollar -> cont 11#;+	Ident happy_dollar_dollar -> cont 12#;+	InfixOp happy_dollar_dollar -> cont 13#;+	_ -> happyError' (tk:tks)+	}++happyError_ 14# tk tks = happyError' tks+happyError_ _ tk tks = happyError' (tk:tks)++happyThen :: () => Either String a -> (a -> Either String b) -> Either String b+happyThen = (>>=)+happyReturn :: () => a -> Either String a+happyReturn = (return)+happyThen1 m k tks = (>>=) m (\a -> k a tks)+happyReturn1 :: () => a -> b -> Either String a+happyReturn1 = \a tks -> (return) a+happyError' :: () => [(Token)] -> Either String a+happyError' = parseError++parser tks = happySomeParser where+  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))++happySeq = happyDontSeq+++parseError :: [Token] -> Either String a+parseError ts = Left $ "Parse error: " ++ show ts++-- | A simple expression language AST, for things parsed from 'String' or JSON structures.+data ExprH+    = SrcName String                -- ^ Variable names (refers to source code).+    | CmdName String                -- ^ Commands (to be looked up in 'HERMIT.Dictionary').+    | AppH ExprH ExprH              -- ^ Application.+    | CoreH String                  -- ^ Core Fragment+    | ListH [ExprH]                 -- ^ List of expressions+    deriving (Eq, Show)++data Token+    = ParenLeft+    | ParenRight+    | ScopeStart+    | ScopeEnd+    | ListStart+    | ListDelim+    | ListEnd+    | StmtEnd+    | Tick+    | CoreString String+    | Quote String+    | Ident String+    | InfixOp String+    deriving (Eq, Show)++lexError :: String -> Either String a+lexError msg = Left ("Lexer error: " ++ msg)++lexer :: String -> Either String [Token]+lexer []           = Right []+lexer ('\n':cs)    = fmap (StmtEnd:)    $ lexer cs+lexer (';' :cs)    = fmap (StmtEnd:)    $ lexer cs+lexer ('(' :cs)    = fmap (ParenLeft:)  $ lexer cs+lexer (')' :cs)    = fmap (ParenRight:) $ lexer cs+lexer ('{' :cs)    = fmap (ScopeStart:) $ lexer cs+lexer ('}' :cs)    = fmap (ScopeEnd:)   $ lexer cs+lexer ('\'':cs)    = fmap (Tick:)       $ lexer cs+lexer ('\"':cs)    = do (str,cs') <- lexString cs+                        fmap (Quote str:) $ lexer cs'+lexer ('[':'|':cs) = do (str,cs') <- lexCore cs+                        fmap (CoreString str:) $ lexer cs'+lexer ('-':'-':cs) = let (_,s') = span (/= '\n') cs in lexer s'+lexer ('[' :cs)    = fmap (ListStart:)  $ lexer cs+lexer (',' :cs)    = fmap (ListDelim:)  $ lexer cs+lexer (']' :cs)    = fmap (ListEnd:)    $ lexer cs+lexer s@(c:cs)     | isSpace             c = lexer cs+                   | isScriptIdFirstChar c = let (i,s') = span isScriptIdChar s+                                              in fmap (Ident i:) $ lexer s'+                   | isScriptInfixIdChar c = let (op,s') = span isScriptInfixIdChar s+                                              in fmap (InfixOp op:) $ lexer s'+lexer s            = lexError $ "no match on " ++ s++lexString :: String -> Either String (String,String)+lexString ('\"':cs)      = Right ([],cs)+lexString ('\\':'\"':cs) = do (c',r) <- lexString cs+                              return ('"':c',r)+lexString (c:cs)         = do (c',r) <- lexString cs+                              return (c:c',r)+lexString []             = lexError "no matching quote"++lexCore :: String -> Either String (String,String)+lexCore ('|':']':rest) = Right ([],rest)+lexCore (c:cs)         = do (c',r) <- lexCore cs+                            return (c:c',r)+lexCore []             = lexError "no closing |]"++---------------------------------------------++-- | Use ghci Parser.hs to run this test function.+test = do+    ln <- getLine+    case ln of+        "quit" -> return ()+        _      -> do print $ lexer ln+                     print $ parseScript ln+                     test++type Script = [ExprH]++parseScript :: String -> Either String Script+parseScript = lexer >=> parser++---------------------------------------------++unparseScript :: Script -> String+unparseScript = intercalate " ; " . map unparseExprH++unparseExprH :: ExprH -> String+unparseExprH (SrcName nm)+    | nm /= "" && (all isScriptInfixIdChar nm || isScriptIdFirstChar (head nm) && all isScriptIdChar (tail nm)) = "'" ++ nm+    | otherwise = "'\"" ++ concatMap escape nm ++ "\""+        where escape '\"' = "\\\""+              escape c    = [c]+unparseExprH (CmdName nm)+    | nm == "{"             = "{ "+    | nm == "}"             = " }"+    | all isScriptIdChar nm = nm+    | otherwise             = show nm     -- with quotes+unparseExprH (AppH (AppH (CmdName nm) e1) e2)+    | all isScriptInfixIdChar nm+    = unparseAtom e1 ++ " " ++ nm ++ " " ++ unparseAtom e2+unparseExprH (AppH e1 e2) = unparseExprH e1 ++ " " ++ unparseAtom e2+unparseExprH (CoreH s)    = "[|" ++ s ++ "|]"+unparseExprH (ListH es)   = "[" ++ intercalate "," (map unparseExprH es) ++ "]"++unparseAtom :: ExprH -> String+unparseAtom e@(AppH {}) = "(" ++ unparseExprH e ++ ")"+unparseAtom e           = unparseExprH e++---------------------------------------------+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp ++{-# LINE 13 "templates/GenericTemplate.hs" #-}++++++#if __GLASGOW_HASKELL__ > 706+#define LT(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.<# m)) :: Bool)+#define GTE(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.>=# m)) :: Bool)+#define EQ(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.==# m)) :: Bool)+#else+#define LT(n,m) (n Happy_GHC_Exts.<# m)+#define GTE(n,m) (n Happy_GHC_Exts.>=# m)+#define EQ(n,m) (n Happy_GHC_Exts.==# m)+#endif+{-# LINE 45 "templates/GenericTemplate.hs" #-}+++data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList++++++{-# LINE 66 "templates/GenericTemplate.hs" #-}++{-# LINE 76 "templates/GenericTemplate.hs" #-}++{-# LINE 85 "templates/GenericTemplate.hs" #-}++infixr 9 `HappyStk`+data HappyStk a = HappyStk a (HappyStk a)++-----------------------------------------------------------------------------+-- starting the parse++happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll++-----------------------------------------------------------------------------+-- Accepting the parse++-- If the current token is 0#, it means we've just accepted a partial+-- parse (a %partial parser).  We must ignore the saved token on the top of+-- the stack in this case.+happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =+	happyReturn1 ans+happyAccept j tk st sts (HappyStk ans _) = +	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)++-----------------------------------------------------------------------------+-- Arrays only: do the next action++++happyDoAction i tk st+	= {- nothing -}+++	  case action of+		0#		  -> {- nothing -}+				     happyFail i tk st+		-1# 	  -> {- nothing -}+				     happyAccept i tk st+		n | LT(n,(0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}++				     (happyReduceArr Happy_Data_Array.! rule) i tk st+				     where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))+		n		  -> {- nothing -}+++				     happyShift new_state i tk st+                                     where new_state = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))+   where off    = indexShortOffAddr happyActOffsets st+         off_i  = (off Happy_GHC_Exts.+# i)+	 check  = if GTE(off_i,(0# :: Happy_GHC_Exts.Int#))+                  then EQ(indexShortOffAddr happyCheck off_i, i)+		  else False+         action+          | check     = indexShortOffAddr happyTable off_i+          | otherwise = indexShortOffAddr happyDefActions st+++indexShortOffAddr (HappyA# arr) off =+	Happy_GHC_Exts.narrow16Int# i+  where+        i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)+        high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))+        low  = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))+        off' = off Happy_GHC_Exts.*# 2#++++++data HappyAddr = HappyA# Happy_GHC_Exts.Addr#+++++-----------------------------------------------------------------------------+-- HappyState data type (not arrays)++{-# LINE 169 "templates/GenericTemplate.hs" #-}++-----------------------------------------------------------------------------+-- Shifting a token++happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =+     let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in+--     trace "shifting the error token" $+     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)++happyShift new_state i tk st sts stk =+     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)++-- happyReduce is specialised for the common cases.++happySpecReduce_0 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_0 nt fn j tk st@((action)) sts stk+     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)++happySpecReduce_1 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')+     = let r = fn v1 in+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_2 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')+     = let r = fn v1 v2 in+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_3 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')+     = let r = fn v1 v2 v3 in+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happyReduce k i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happyReduce k nt fn j tk st sts stk+     = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of+	 sts1@((HappyCons (st1@(action)) (_))) ->+        	let r = fn stk in  -- it doesn't hurt to always seq here...+       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)++happyMonadReduce k nt fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happyMonadReduce k nt fn j tk st sts stk =+      case happyDrop k (HappyCons (st) (sts)) of+        sts1@((HappyCons (st1@(action)) (_))) ->+          let drop_stk = happyDropStk k stk in+          happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))++happyMonad2Reduce k nt fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happyMonad2Reduce k nt fn j tk st sts stk =+      case happyDrop k (HappyCons (st) (sts)) of+        sts1@((HappyCons (st1@(action)) (_))) ->+         let drop_stk = happyDropStk k stk++             off = indexShortOffAddr happyGotoOffsets st1+             off_i = (off Happy_GHC_Exts.+# nt)+             new_state = indexShortOffAddr happyTable off_i++++          in+          happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))++happyDrop 0# l = l+happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t++happyDropStk 0# l = l+happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs++-----------------------------------------------------------------------------+-- Moving to a new state after a reduction+++happyGoto nt j tk st = +   {- nothing -}+   happyDoAction j tk new_state+   where off = indexShortOffAddr happyGotoOffsets st+         off_i = (off Happy_GHC_Exts.+# nt)+         new_state = indexShortOffAddr happyTable off_i+++++-----------------------------------------------------------------------------+-- Error recovery (0# is the error token)++-- parse error if we are in recovery and we fail again+happyFail 0# tk old_st _ stk@(x `HappyStk` _) =+     let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in+--	trace "failing" $ +        happyError_ i tk++{-  We don't need state discarding for our restricted implementation of+    "error".  In fact, it can cause some bogus parses, so I've disabled it+    for now --SDM++-- discard a state+happyFail  0# tk old_st (HappyCons ((action)) (sts)) +						(saved_tok `HappyStk` _ `HappyStk` stk) =+--	trace ("discarding state, depth " ++ show (length stk))  $+	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))+-}++-- Enter error recovery: generate an error token,+--                       save the old token and carry on.+happyFail  i tk (action) sts stk =+--      trace "entering error recovery" $+	happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)++-- Internal happy errors:++notHappyAtAll :: a+notHappyAtAll = error "Internal Happy error\n"++-----------------------------------------------------------------------------+-- Hack to get the typechecker to accept our action functions+++happyTcHack :: Happy_GHC_Exts.Int# -> a -> a+happyTcHack x y = y+{-# INLINE happyTcHack #-}+++-----------------------------------------------------------------------------+-- Seq-ing.  If the --strict flag is given, then Happy emits +--	happySeq = happyDoSeq+-- otherwise it emits+-- 	happySeq = happyDontSeq++happyDoSeq, happyDontSeq :: a -> b -> b+happyDoSeq   a b = a `seq` b+happyDontSeq a b = b++-----------------------------------------------------------------------------+-- Don't inline any functions from the template.  GHC has a nasty habit+-- of deciding to inline happyGoto everywhere, which increases the size of+-- the generated parser quite a bit.+++{-# NOINLINE happyDoAction #-}+{-# NOINLINE happyTable #-}+{-# NOINLINE happyCheck #-}+{-# NOINLINE happyActOffsets #-}+{-# NOINLINE happyGotoOffsets #-}+{-# NOINLINE happyDefActions #-}++{-# NOINLINE happyShift #-}+{-# NOINLINE happySpecReduce_0 #-}+{-# NOINLINE happySpecReduce_1 #-}+{-# NOINLINE happySpecReduce_2 #-}+{-# NOINLINE happySpecReduce_3 #-}+{-# NOINLINE happyReduce #-}+{-# NOINLINE happyMonadReduce #-}+{-# NOINLINE happyGoto #-}+{-# NOINLINE happyFail #-}++-- end of Happy Template.
+ dist/build/HERMIT/ParserCore.hs view
@@ -0,0 +1,624 @@+{-# OPTIONS_GHC -w #-}+{-# OPTIONS -fglasgow-exts -cpp #-}+{-# LANGUAGE CPP #-}+ module HERMIT.ParserCore (parseCore, parseCoreExprT, parse2beforeBiR, parse3beforeBiR) where++import Control.Arrow+import Control.Monad.Reader+import Data.Char (isSpace, isDigit)++import HERMIT.Context+import HERMIT.External+import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Syntax (isCoreInfixIdChar, isCoreIdFirstChar, isCoreIdChar)++import HERMIT.Dictionary.Common++import Language.KURE.MonadCatch (prefixFailMsg)++import Language.Haskell.TH as TH+import qualified Data.Array as Happy_Data_Array+import qualified GHC.Exts as Happy_GHC_Exts++-- parser produced by Happy Version 1.19.0++newtype HappyAbsSyn t4 t5 t6 t7 t8 t9 = HappyAbsSyn HappyAny+#if __GLASGOW_HASKELL__ >= 607+type HappyAny = Happy_GHC_Exts.Any+#else+type HappyAny = forall a . a+#endif+happyIn4 :: t4 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn4 #-}+happyOut4 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t4+happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut4 #-}+happyIn5 :: t5 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn5 #-}+happyOut5 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t5+happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut5 #-}+happyIn6 :: t6 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn6 #-}+happyOut6 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t6+happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut6 #-}+happyIn7 :: t7 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn7 #-}+happyOut7 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t7+happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut7 #-}+happyIn8 :: t8 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn8 #-}+happyOut8 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t8+happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut8 #-}+happyIn9 :: t9 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn9 #-}+happyOut9 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t9+happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut9 #-}+happyInTok :: (Token) -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)+happyInTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyInTok #-}+happyOutTok :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> (Token)+happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOutTok #-}+++happyActOffsets :: HappyAddr+happyActOffsets = HappyA# "\xf8\xff\xf8\xff\xf8\xff\x00\x00\x00\x00\x00\x00\x00\x00\xf5\xff\x00\x00\x00\x00\x00\x00\xf0\xff\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00"#++happyGotoOffsets :: HappyAddr+happyGotoOffsets = HappyA# "\x0b\x00\x18\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++happyDefActions :: HappyAddr+happyDefActions = HappyA# "\x00\x00\x00\x00\xfe\xff\xfc\xff\xf8\xff\xf7\xff\xf9\xff\x00\x00\xf4\xff\xf6\xff\xf5\xff\x00\x00\x00\x00\xfa\xff\xfd\xff\xfb\xff"#++happyCheck :: HappyAddr+happyCheck = HappyA# "\xff\xff\x0c\x00\x0d\x00\x0d\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x1c\x00\x22\x00\x1e\x00\x1c\x00\x20\x00\x1e\x00\xff\xff\x20\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x02\x00\x03\x00\x04\x00\x05\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++happyTable :: HappyAddr+happyTable = HappyA# "\x00\x00\x08\x00\x0e\x00\x10\x00\x08\x00\x0c\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x0b\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x09\x00\xff\xff\x0a\x00\x09\x00\x0b\x00\x0a\x00\x00\x00\x0b\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x0e\x00\x04\x00\x05\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++happyReduceArr = Happy_Data_Array.array (1, 11) [+	(1 , happyReduce_1),+	(2 , happyReduce_2),+	(3 , happyReduce_3),+	(4 , happyReduce_4),+	(5 , happyReduce_5),+	(6 , happyReduce_6),+	(7 , happyReduce_7),+	(8 , happyReduce_8),+	(9 , happyReduce_9),+	(10 , happyReduce_10),+	(11 , happyReduce_11)+	]++happy_n_terms = 35 :: Int+happy_n_nonterms = 6 :: Int++happyReduce_1 = happySpecReduce_1  0# happyReduction_1+happyReduction_1 happy_x_1+	 =  case happyOut5 happy_x_1 of { happy_var_1 -> +	happyIn4+		 (happy_var_1+	)}++happyReduce_2 = happySpecReduce_2  1# happyReduction_2+happyReduction_2 happy_x_2+	happy_x_1+	 =  case happyOut5 happy_x_1 of { happy_var_1 -> +	case happyOut6 happy_x_2 of { happy_var_2 -> +	happyIn5+		 (App happy_var_1 happy_var_2+	)}}++happyReduce_3 = happySpecReduce_1  1# happyReduction_3+happyReduction_3 happy_x_1+	 =  case happyOut6 happy_x_1 of { happy_var_1 -> +	happyIn5+		 (happy_var_1+	)}++happyReduce_4 = happySpecReduce_3  2# happyReduction_4+happyReduction_4 happy_x_3+	happy_x_2+	happy_x_1+	 =  case happyOut4 happy_x_2 of { happy_var_2 -> +	happyIn6+		 (happy_var_2+	)}++happyReduce_5 = happyMonadReduce 2# 2# happyReduction_5+happyReduction_5 (happy_x_2 `HappyStk`+	happy_x_1 `HappyStk`+	happyRest) tk+	 = happyThen (( lookupName "()" Var)+	) (\r -> happyReturn (happyIn6 r))++happyReduce_6 = happySpecReduce_1  2# happyReduction_6+happyReduction_6 happy_x_1+	 =  case happyOut9 happy_x_1 of { happy_var_1 -> +	happyIn6+		 (happy_var_1+	)}++happyReduce_7 = happySpecReduce_1  2# happyReduction_7+happyReduction_7 happy_x_1+	 =  case happyOut7 happy_x_1 of { happy_var_1 -> +	happyIn6+		 (happy_var_1+	)}++happyReduce_8 = happySpecReduce_1  2# happyReduction_8+happyReduction_8 happy_x_1+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> +	happyIn6+		 (happy_var_1+	)}++happyReduce_9 = happyMonadReduce 1# 3# happyReduction_9+happyReduction_9 (happy_x_1 `HappyStk`+	happyRest) tk+	 = happyThen (case happyOutTok happy_x_1 of { (Tinteger happy_var_1) -> +	( mkIntExpr' happy_var_1)}+	) (\r -> happyReturn (happyIn7 r))++happyReduce_10 = happyMonadReduce 1# 4# happyReduction_10+happyReduction_10 (happy_x_1 `HappyStk`+	happyRest) tk+	 = happyThen (case happyOutTok happy_x_1 of { (Tstring happy_var_1) -> +	( lift $ mkStringExpr happy_var_1)}+	) (\r -> happyReturn (happyIn8 r))++happyReduce_11 = happyMonadReduce 1# 5# happyReduction_11+happyReduction_11 (happy_x_1 `HappyStk`+	happyRest) tk+	 = happyThen (case happyOutTok happy_x_1 of { (Tname happy_var_1) -> +	( lookupName happy_var_1 varToCoreExpr)}+	) (\r -> happyReturn (happyIn9 r))++happyNewToken action sts stk [] =+	happyDoAction 34# notHappyAtAll action sts stk []++happyNewToken action sts stk (tk:tks) =+	let cont i = happyDoAction i tk action sts stk tks in+	case tk of {+	Tforall -> cont 1#;+	Trec -> cont 2#;+	Tlet -> cont 3#;+	Tin -> cont 4#;+	Tcase -> cont 5#;+	Tof -> cont 6#;+	Tcast -> cont 7#;+	Tnote -> cont 8#;+	Texternal -> cont 9#;+	Tlocal -> cont 10#;+	Twild -> cont 11#;+	Toparen -> cont 12#;+	Tcparen -> cont 13#;+	Tobrace -> cont 14#;+	Tcbrace -> cont 15#;+	Thash -> cont 16#;+	Teq -> cont 17#;+	Tcolon -> cont 18#;+	Tcoloncolon -> cont 19#;+	Tcoloneqcolon -> cont 20#;+	Tstar -> cont 21#;+	Tarrow -> cont 22#;+	Tlambda -> cont 23#;+	Tat -> cont 24#;+	Tdot -> cont 25#;+	Tquestion -> cont 26#;+	Tsemicolon -> cont 27#;+	Tname happy_dollar_dollar -> cont 28#;+	Tcname happy_dollar_dollar -> cont 29#;+	Tinteger happy_dollar_dollar -> cont 30#;+	Trational happy_dollar_dollar -> cont 31#;+	Tstring happy_dollar_dollar -> cont 32#;+	Tchar happy_dollar_dollar -> cont 33#;+	_ -> happyError' (tk:tks)+	}++happyError_ 34# tk tks = happyError' tks+happyError_ _ tk tks = happyError' (tk:tks)++happyThen :: () => CoreParseM a -> (a -> CoreParseM b) -> CoreParseM b+happyThen = (>>=)+happyReturn :: () => a -> CoreParseM a+happyReturn = (return)+happyThen1 m k tks = (>>=) m (\a -> k a tks)+happyReturn1 :: () => a -> b -> CoreParseM a+happyReturn1 = \a tks -> (return) a+happyError' :: () => [(Token)] -> CoreParseM a+happyError' = parseError++parser tks = happySomeParser where+  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))++happySeq = happyDontSeq+++mkIntExpr' :: Integer -> CoreParseM CoreExpr+#if __GLASGOW_HASKELL__ > 706+mkIntExpr' i = do+    dflags <- lift getDynFlags+    return $ mkIntExpr dflags i+#else+mkIntExpr' i = return $ mkIntExpr i+#endif++lookupName :: String -> (Id -> CoreExpr) -> CoreParseM CoreExpr+lookupName nm k = do+    c <- ask+    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId (TH.mkName nm) c+    return (k v)++type CoreParseM a = ReaderT HermitC HermitM a++parseError :: Monad m => [Token] -> m a+parseError ts = fail $ "core parse error: " ++ show ts++data Token+    = Tforall+    | Trec+    | Tlet+    | Tin+    | Tcase+    | Tof+    | Tcast+    | Tnote+    | Texternal+    | Tlocal+    | Twild --+    | Toparen --+    | Tcparen --+    | Tobrace+    | Tcbrace+    | Thash+    | Teq+    | Tcolon --+    | Tcoloncolon --+    | Tcoloneqcolon+    | Tstar+    | Tarrow+    | Tlambda --+    | Tat+    | Tdot+    | Tquestion+    | Tsemicolon+    | Tname String+    | Tcname String+    | Tinteger Integer+    | Trational Float+    | Tstring String+    | Tchar Char+    deriving (Eq, Show)++lexer :: String -> Either String [Token]+lexer []           = Right []+lexer ('_' :cs)    = fmap (Twild:)       $ lexer cs+lexer ('(' :cs)    = fmap (Toparen:)     $ lexer cs+lexer (')' :cs)    = fmap (Tcparen:)     $ lexer cs+lexer (':':':':cs) = fmap (Tcoloncolon:) $ lexer cs+-- lexer (':' :cs)    = fmap (Tcolon:)      $ lexer cs+lexer ('\\':cs)    = fmap (Tlambda:)     $ lexer cs+lexer ('-':'>':cs) = fmap (Tarrow:)      $ lexer cs+lexer ('\"':cs)    = let (str,rest) = span (/='\"') cs+                     in case rest of+                           ('\"':cs') -> fmap (Tstring str:) $ lexer cs'+                           _          -> Left "lexer: no matching quote"+lexer s@(c:cs) | isSpace           c = lexer cs+               | isDigit           c = let (i,s') = span isDigit s+                                         in fmap (Tinteger (read i):) $ lexer s'+               | isCoreIdFirstChar c = let (i,s') = span isCoreIdChar s+                                         in fmap (Tname i:) $ lexer s'+               | isCoreInfixIdChar c = let (op,s') = span isCoreInfixIdChar s+                                         in fmap (Tname op:) $ lexer s'+lexer s            = Left $ "lexer: no match on " ++ s++---------------------------------------------++parseCore :: CoreString -> HermitC -> HermitM CoreExpr+parseCore (CoreString s) c =+    case lexer s of+        Left msg -> fail msg+        Right tokens -> runReaderT (parser tokens) c++---------------------------------------------++-- These three should probably go somewhere else.++-- | Parse a 'CoreString' to a 'CoreExpr', using the current context.+parseCoreExprT :: CoreString -> TranslateH a CoreExpr+parseCoreExprT = contextonlyT . parseCore++parse2beforeBiR :: (CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> BiRewriteH a+parse2beforeBiR f s1 s2 = beforeBiR (parseCoreExprT s1 &&& parseCoreExprT s2) (uncurry f)++parse3beforeBiR :: (CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> CoreString -> BiRewriteH a+parse3beforeBiR f s1 s2 s3 = beforeBiR ((parseCoreExprT s1 &&& parseCoreExprT s2) &&& parseCoreExprT s3) ((uncurry.uncurry) f)++---------------------------------------------+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp ++{-# LINE 13 "templates/GenericTemplate.hs" #-}++++++#if __GLASGOW_HASKELL__ > 706+#define LT(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.<# m)) :: Bool)+#define GTE(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.>=# m)) :: Bool)+#define EQ(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.==# m)) :: Bool)+#else+#define LT(n,m) (n Happy_GHC_Exts.<# m)+#define GTE(n,m) (n Happy_GHC_Exts.>=# m)+#define EQ(n,m) (n Happy_GHC_Exts.==# m)+#endif+{-# LINE 45 "templates/GenericTemplate.hs" #-}+++data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList++++++{-# LINE 66 "templates/GenericTemplate.hs" #-}++{-# LINE 76 "templates/GenericTemplate.hs" #-}++{-# LINE 85 "templates/GenericTemplate.hs" #-}++infixr 9 `HappyStk`+data HappyStk a = HappyStk a (HappyStk a)++-----------------------------------------------------------------------------+-- starting the parse++happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll++-----------------------------------------------------------------------------+-- Accepting the parse++-- If the current token is 0#, it means we've just accepted a partial+-- parse (a %partial parser).  We must ignore the saved token on the top of+-- the stack in this case.+happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =+	happyReturn1 ans+happyAccept j tk st sts (HappyStk ans _) = +	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)++-----------------------------------------------------------------------------+-- Arrays only: do the next action++++happyDoAction i tk st+	= {- nothing -}+++	  case action of+		0#		  -> {- nothing -}+				     happyFail i tk st+		-1# 	  -> {- nothing -}+				     happyAccept i tk st+		n | LT(n,(0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}++				     (happyReduceArr Happy_Data_Array.! rule) i tk st+				     where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))+		n		  -> {- nothing -}+++				     happyShift new_state i tk st+                                     where new_state = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))+   where off    = indexShortOffAddr happyActOffsets st+         off_i  = (off Happy_GHC_Exts.+# i)+	 check  = if GTE(off_i,(0# :: Happy_GHC_Exts.Int#))+                  then EQ(indexShortOffAddr happyCheck off_i, i)+		  else False+         action+          | check     = indexShortOffAddr happyTable off_i+          | otherwise = indexShortOffAddr happyDefActions st+++indexShortOffAddr (HappyA# arr) off =+	Happy_GHC_Exts.narrow16Int# i+  where+        i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)+        high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))+        low  = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))+        off' = off Happy_GHC_Exts.*# 2#++++++data HappyAddr = HappyA# Happy_GHC_Exts.Addr#+++++-----------------------------------------------------------------------------+-- HappyState data type (not arrays)++{-# LINE 169 "templates/GenericTemplate.hs" #-}++-----------------------------------------------------------------------------+-- Shifting a token++happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =+     let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in+--     trace "shifting the error token" $+     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)++happyShift new_state i tk st sts stk =+     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)++-- happyReduce is specialised for the common cases.++happySpecReduce_0 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_0 nt fn j tk st@((action)) sts stk+     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)++happySpecReduce_1 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')+     = let r = fn v1 in+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_2 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')+     = let r = fn v1 v2 in+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_3 i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')+     = let r = fn v1 v2 v3 in+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happyReduce k i fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happyReduce k nt fn j tk st sts stk+     = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of+	 sts1@((HappyCons (st1@(action)) (_))) ->+        	let r = fn stk in  -- it doesn't hurt to always seq here...+       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)++happyMonadReduce k nt fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happyMonadReduce k nt fn j tk st sts stk =+      case happyDrop k (HappyCons (st) (sts)) of+        sts1@((HappyCons (st1@(action)) (_))) ->+          let drop_stk = happyDropStk k stk in+          happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))++happyMonad2Reduce k nt fn 0# tk st sts stk+     = happyFail 0# tk st sts stk+happyMonad2Reduce k nt fn j tk st sts stk =+      case happyDrop k (HappyCons (st) (sts)) of+        sts1@((HappyCons (st1@(action)) (_))) ->+         let drop_stk = happyDropStk k stk++             off = indexShortOffAddr happyGotoOffsets st1+             off_i = (off Happy_GHC_Exts.+# nt)+             new_state = indexShortOffAddr happyTable off_i++++          in+          happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))++happyDrop 0# l = l+happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t++happyDropStk 0# l = l+happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs++-----------------------------------------------------------------------------+-- Moving to a new state after a reduction+++happyGoto nt j tk st = +   {- nothing -}+   happyDoAction j tk new_state+   where off = indexShortOffAddr happyGotoOffsets st+         off_i = (off Happy_GHC_Exts.+# nt)+         new_state = indexShortOffAddr happyTable off_i+++++-----------------------------------------------------------------------------+-- Error recovery (0# is the error token)++-- parse error if we are in recovery and we fail again+happyFail 0# tk old_st _ stk@(x `HappyStk` _) =+     let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in+--	trace "failing" $ +        happyError_ i tk++{-  We don't need state discarding for our restricted implementation of+    "error".  In fact, it can cause some bogus parses, so I've disabled it+    for now --SDM++-- discard a state+happyFail  0# tk old_st (HappyCons ((action)) (sts)) +						(saved_tok `HappyStk` _ `HappyStk` stk) =+--	trace ("discarding state, depth " ++ show (length stk))  $+	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))+-}++-- Enter error recovery: generate an error token,+--                       save the old token and carry on.+happyFail  i tk (action) sts stk =+--      trace "entering error recovery" $+	happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)++-- Internal happy errors:++notHappyAtAll :: a+notHappyAtAll = error "Internal Happy error\n"++-----------------------------------------------------------------------------+-- Hack to get the typechecker to accept our action functions+++happyTcHack :: Happy_GHC_Exts.Int# -> a -> a+happyTcHack x y = y+{-# INLINE happyTcHack #-}+++-----------------------------------------------------------------------------+-- Seq-ing.  If the --strict flag is given, then Happy emits +--	happySeq = happyDoSeq+-- otherwise it emits+-- 	happySeq = happyDontSeq++happyDoSeq, happyDontSeq :: a -> b -> b+happyDoSeq   a b = a `seq` b+happyDontSeq a b = b++-----------------------------------------------------------------------------+-- Don't inline any functions from the template.  GHC has a nasty habit+-- of deciding to inline happyGoto everywhere, which increases the size of+-- the generated parser quite a bit.+++{-# NOINLINE happyDoAction #-}+{-# NOINLINE happyTable #-}+{-# NOINLINE happyCheck #-}+{-# NOINLINE happyActOffsets #-}+{-# NOINLINE happyGotoOffsets #-}+{-# NOINLINE happyDefActions #-}++{-# NOINLINE happyShift #-}+{-# NOINLINE happySpecReduce_0 #-}+{-# NOINLINE happySpecReduce_1 #-}+{-# NOINLINE happySpecReduce_2 #-}+{-# NOINLINE happySpecReduce_3 #-}+{-# NOINLINE happyReduce #-}+{-# NOINLINE happyMonadReduce #-}+{-# NOINLINE happyGoto #-}+{-# NOINLINE happyFail #-}++-- end of Happy Template.
− dist/build/Language/HERMIT/Parser.hs
@@ -1,728 +0,0 @@-{-# OPTIONS_GHC -w #-}-{-# OPTIONS -fglasgow-exts -cpp #-}-module Language.HERMIT.Parser-    ( parseStmtsH-    , unparseExprH-    , numStmtsH-    , ExprH(..)-    ) where--import Data.Char (isSpace)-import Data.List (intercalate)--import Language.HERMIT.Syntax (isScriptInfixIdChar, isScriptIdFirstChar, isScriptIdChar)-import qualified Data.Array as Happy_Data_Array-import qualified GHC.Exts as Happy_GHC_Exts---- parser produced by Happy Version 1.18.6--newtype HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 = HappyAbsSyn HappyAny-#if __GLASGOW_HASKELL__ >= 607-type HappyAny = Happy_GHC_Exts.Any-#else-type HappyAny = forall a . a-#endif-happyIn4 :: t4 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn4 #-}-happyOut4 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t4-happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut4 #-}-happyIn5 :: t5 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn5 #-}-happyOut5 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t5-happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut5 #-}-happyIn6 :: t6 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn6 #-}-happyOut6 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t6-happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut6 #-}-happyIn7 :: t7 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn7 #-}-happyOut7 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t7-happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut7 #-}-happyIn8 :: t8 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn8 #-}-happyOut8 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t8-happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut8 #-}-happyIn9 :: t9 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn9 #-}-happyOut9 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t9-happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut9 #-}-happyIn10 :: t10 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn10 #-}-happyOut10 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t10-happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut10 #-}-happyIn11 :: t11 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn11 #-}-happyOut11 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> t11-happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut11 #-}-happyInTok :: (Token) -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11)-happyInTok x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyInTok #-}-happyOutTok :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11) -> (Token)-happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOutTok #-}---happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\x0e\x00\x1e\x00\x0e\x00\x06\x00\x00\x00\x00\x00\xfd\xff\x01\x00\x00\x00\x1a\x00\x0e\x00\x1a\x00\x0e\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x09\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00"#--happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\x45\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00\x4d\x00\x39\x00\x48\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x2d\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00"#--happyDefActions :: HappyAddr-happyDefActions = HappyA# "\xfa\xff\x00\x00\xfa\xff\x00\x00\xfc\xff\xfb\xff\xf9\xff\xf4\xff\xf2\xff\x00\x00\xfa\xff\xe8\xff\xfa\xff\x00\x00\xed\xff\xee\xff\xea\xff\xef\xff\xf1\xff\xf0\xff\xf6\xff\xe7\xff\x00\x00\xe9\xff\xfd\xff\x00\x00\xf3\xff\x00\x00\xfa\xff\xfa\xff\xfe\xff\xf7\xff\xf8\xff\xf5\xff\xeb\xff\xec\xff\x00\x00\xe6\xff"#--happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x04\x00\x01\x00\x05\x00\x02\x00\x08\x00\x05\x00\x03\x00\x04\x00\x05\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x01\x00\x07\x00\x03\x00\x04\x00\x05\x00\x0e\x00\x06\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x01\x00\x03\x00\x04\x00\x05\x00\x05\x00\x07\x00\x03\x00\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x03\x00\x04\x00\x05\x00\xff\xff\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#--happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x1d\x00\x0a\x00\x1a\x00\x23\x00\x1e\x00\x0c\x00\x21\x00\x07\x00\x08\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1c\x00\x0a\x00\x24\x00\x03\x00\x0b\x00\x0c\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x0a\x00\x15\x00\x07\x00\x08\x00\x0c\x00\x25\x00\x03\x00\x00\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1f\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x20\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x14\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x18\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x1e\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x15\x00\x07\x00\x08\x00\x16\x00\x17\x00\x19\x00\x07\x00\x08\x00\x00\x00\x12\x00\x13\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#--happyReduceArr = Happy_Data_Array.array (1, 25) [-	(1 , happyReduce_1),-	(2 , happyReduce_2),-	(3 , happyReduce_3),-	(4 , happyReduce_4),-	(5 , happyReduce_5),-	(6 , happyReduce_6),-	(7 , happyReduce_7),-	(8 , happyReduce_8),-	(9 , happyReduce_9),-	(10 , happyReduce_10),-	(11 , happyReduce_11),-	(12 , happyReduce_12),-	(13 , happyReduce_13),-	(14 , happyReduce_14),-	(15 , happyReduce_15),-	(16 , happyReduce_16),-	(17 , happyReduce_17),-	(18 , happyReduce_18),-	(19 , happyReduce_19),-	(20 , happyReduce_20),-	(21 , happyReduce_21),-	(22 , happyReduce_22),-	(23 , happyReduce_23),-	(24 , happyReduce_24),-	(25 , happyReduce_25)-	]--happy_n_terms = 15 :: Int-happy_n_nonterms = 8 :: Int--happyReduce_1 = happySpecReduce_2  0# happyReduction_1-happyReduction_1 happy_x_2-	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn4-		 (CmdName "{" : happy_var_2-	)}--happyReduce_2 = happySpecReduce_2  0# happyReduction_2-happyReduction_2 happy_x_2-	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn4-		 (CmdName "}" : happy_var_2-	)}--happyReduce_3 = happySpecReduce_1  0# happyReduction_3-happyReduction_3 happy_x_1-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> -	happyIn4-		 (happy_var_1-	)}--happyReduce_4 = happySpecReduce_1  1# happyReduction_4-happyReduction_4 happy_x_1-	 =  case happyOut6 happy_x_1 of { happy_var_1 -> -	happyIn5-		 (happy_var_1-	)}--happyReduce_5 = happySpecReduce_0  1# happyReduction_5-happyReduction_5  =  happyIn5-		 ([]-	)--happyReduce_6 = happySpecReduce_1  2# happyReduction_6-happyReduction_6 happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	happyIn6-		 ([happy_var_1]-	)}--happyReduce_7 = happySpecReduce_3  2# happyReduction_7-happyReduction_7 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	case happyOut4 happy_x_3 of { happy_var_3 -> -	happyIn6-		 ([happy_var_1, CmdName "}"] ++ happy_var_3-	)}}--happyReduce_8 = happySpecReduce_3  2# happyReduction_8-happyReduction_8 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	case happyOut4 happy_x_3 of { happy_var_3 -> -	happyIn6-		 (happy_var_1 : happy_var_3-	)}}--happyReduce_9 = happySpecReduce_2  2# happyReduction_9-happyReduction_9 happy_x_2-	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn6-		 (happy_var_2-	)}--happyReduce_10 = happySpecReduce_3  3# happyReduction_10-happyReduction_10 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> -	case happyOutTok happy_x_2 of { (InfixOp happy_var_2) -> -	case happyOut7 happy_x_3 of { happy_var_3 -> -	happyIn7-		 (AppH (AppH (CmdName happy_var_2) happy_var_1) happy_var_3-	)}}}--happyReduce_11 = happySpecReduce_1  3# happyReduction_11-happyReduction_11 happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> -	happyIn7-		 (happy_var_1-	)}--happyReduce_12 = happySpecReduce_2  4# happyReduction_12-happyReduction_12 happy_x_2-	happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> -	case happyOut9 happy_x_2 of { happy_var_2 -> -	happyIn8-		 (AppH happy_var_1 happy_var_2-	)}}--happyReduce_13 = happySpecReduce_1  4# happyReduction_13-happyReduction_13 happy_x_1-	 =  case happyOut9 happy_x_1 of { happy_var_1 -> -	happyIn8-		 (happy_var_1-	)}--happyReduce_14 = happySpecReduce_2  5# happyReduction_14-happyReduction_14 happy_x_2-	happy_x_1-	 =  case happyOutTok happy_x_2 of { (Ident happy_var_2) -> -	happyIn9-		 (SrcName happy_var_2-	)}--happyReduce_15 = happySpecReduce_2  5# happyReduction_15-happyReduction_15 happy_x_2-	happy_x_1-	 =  case happyOutTok happy_x_2 of { (InfixOp happy_var_2) -> -	happyIn9-		 (SrcName happy_var_2-	)}--happyReduce_16 = happySpecReduce_2  5# happyReduction_16-happyReduction_16 happy_x_2-	happy_x_1-	 =  case happyOutTok happy_x_2 of { (Quote happy_var_2) -> -	happyIn9-		 (SrcName happy_var_2-	)}--happyReduce_17 = happySpecReduce_1  5# happyReduction_17-happyReduction_17 happy_x_1-	 =  case happyOutTok happy_x_1 of { (Quote happy_var_1) -> -	happyIn9-		 (CmdName happy_var_1-	)}--happyReduce_18 = happySpecReduce_1  5# happyReduction_18-happyReduction_18 happy_x_1-	 =  case happyOutTok happy_x_1 of { (CoreString happy_var_1) -> -	happyIn9-		 (CoreH happy_var_1-	)}--happyReduce_19 = happySpecReduce_3  5# happyReduction_19-happyReduction_19 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut10 happy_x_2 of { happy_var_2 -> -	happyIn9-		 (ListH happy_var_2-	)}--happyReduce_20 = happySpecReduce_3  5# happyReduction_20-happyReduction_20 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut7 happy_x_2 of { happy_var_2 -> -	happyIn9-		 (happy_var_2-	)}--happyReduce_21 = happySpecReduce_1  5# happyReduction_21-happyReduction_21 happy_x_1-	 =  case happyOutTok happy_x_1 of { (Ident happy_var_1) -> -	happyIn9-		 (CmdName happy_var_1-	)}--happyReduce_22 = happySpecReduce_1  6# happyReduction_22-happyReduction_22 happy_x_1-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> -	happyIn10-		 (happy_var_1-	)}--happyReduce_23 = happySpecReduce_0  6# happyReduction_23-happyReduction_23  =  happyIn10-		 ([]-	)--happyReduce_24 = happySpecReduce_1  7# happyReduction_24-happyReduction_24 happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	happyIn11-		 ([happy_var_1]-	)}--happyReduce_25 = happySpecReduce_3  7# happyReduction_25-happyReduction_25 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	case happyOut11 happy_x_3 of { happy_var_3 -> -	happyIn11-		 (happy_var_1 : happy_var_3-	)}}--happyNewToken action sts stk [] =-	happyDoAction 14# notHappyAtAll action sts stk []--happyNewToken action sts stk (tk:tks) =-	let cont i = happyDoAction i tk action sts stk tks in-	case tk of {-	ParenLeft -> cont 1#;-	ParenRight -> cont 2#;-	ScopeStart -> cont 3#;-	ScopeEnd -> cont 4#;-	ListStart -> cont 5#;-	ListDelim -> cont 6#;-	ListEnd -> cont 7#;-	StmtEnd -> cont 8#;-	Tick -> cont 9#;-	CoreString happy_dollar_dollar -> cont 10#;-	Quote happy_dollar_dollar -> cont 11#;-	Ident happy_dollar_dollar -> cont 12#;-	InfixOp happy_dollar_dollar -> cont 13#;-	_ -> happyError' (tk:tks)-	}--happyError_ tk tks = happyError' (tk:tks)--happyThen :: () => Either String a -> (a -> Either String b) -> Either String b-happyThen = (>>=)-happyReturn :: () => a -> Either String a-happyReturn = (return)-happyThen1 m k tks = (>>=) m (\a -> k a tks)-happyReturn1 :: () => a -> b -> Either String a-happyReturn1 = \a tks -> (return) a-happyError' :: () => [(Token)] -> Either String a-happyError' = parseError--parser tks = happySomeParser where-  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))--happySeq = happyDontSeq---parseError :: [Token] -> Either String a-parseError ts = Left $ "parse error: " ++ show ts---- | A simple expression language AST, for things parsed from 'String' or JSON structures.-data ExprH-    = SrcName String                -- ^ Variable names (refers to source code).-    | CmdName String                -- ^ Commands (to be looked up in 'Language.HERMIT.Dictionary').-    | AppH ExprH ExprH              -- ^ Application.-    | CoreH String                  -- ^ Core Fragment-    | ListH [ExprH]                 -- ^ List of expressions-    deriving (Eq, Show)--data Token-    = ParenLeft-    | ParenRight-    | ScopeStart-    | ScopeEnd-    | ListStart-    | ListDelim-    | ListEnd-    | StmtEnd-    | Tick-    | CoreString String-    | Quote String-    | Ident String-    | InfixOp String-    deriving (Eq, Show)--lexer :: String -> Either String [Token]-lexer []           = Right []-lexer ('\n':cs)    = fmap (StmtEnd:)    $ lexer cs-lexer (';' :cs)    = fmap (StmtEnd:)    $ lexer cs-lexer ('(' :cs)    = fmap (ParenLeft:)  $ lexer cs-lexer (')' :cs)    = fmap (ParenRight:) $ lexer cs-lexer ('{' :cs)    = fmap (ScopeStart:) $ lexer cs-lexer ('}' :cs)    = fmap (ScopeEnd:)   $ lexer cs-lexer ('\'':cs)    = fmap (Tick:)       $ lexer cs-lexer ('\"':cs)    = do (str,cs') <- lexString cs-                        fmap (Quote str:) $ lexer cs'-lexer ('[':'|':cs) = do (str,cs') <- lexCore cs-                        fmap (CoreString str:) $ lexer cs'-lexer ('-':'-':cs) = let (_,s') = span (/= '\n') cs in lexer s'-lexer ('[' :cs)    = fmap (ListStart:)  $ lexer cs-lexer (',' :cs)    = fmap (ListDelim:)  $ lexer cs-lexer (']' :cs)    = fmap (ListEnd:)    $ lexer cs-lexer s@(c:cs)     | isSpace             c = lexer cs-                   | isScriptIdFirstChar c = let (i,s') = span isScriptIdChar s-                                              in fmap (Ident i:) $ lexer s'-                   | isScriptInfixIdChar c = let (op,s') = span isScriptInfixIdChar s-                                              in fmap (InfixOp op:) $ lexer s'-lexer s            = Left $ "lexer: no match on " ++ s--lexString :: String -> Either String (String,String)-lexString ('\"':cs)      = Right ([],cs)-lexString ('\\':'\"':cs) = do (c',r) <- lexString cs-                              return ('"':c',r)-lexString (c:cs)         = do (c',r) <- lexString cs-                              return (c:c',r)-lexString []             = Left "lexer: no matching quote"--lexCore :: String -> Either String (String,String)-lexCore ('|':']':rest) = Right ([],rest)-lexCore (c:cs)         = do (c',r) <- lexCore cs-                            return (c:c',r)-lexCore []             = Left "lexer: no closing |]"--------------------------------------------------- | Use ghci Parser.hs to run this test function.-test = do-    ln <- getLine-    case ln of-        "quit" -> return ()-        _      -> do print $ lexer ln-                     print $ parseStmtsH ln-                     test--parseStmtsH :: String -> Either String [ExprH]-parseStmtsH s = lexer s >>= parser--numStmtsH :: [ExprH] -> Int-numStmtsH = length . filter isCounted-    where isCounted (CmdName "{") = False-          isCounted (CmdName "}") = False-          isCounted _             = True------------------------------------------------unparseExprH :: ExprH -> String-unparseExprH (SrcName nm)-    | nm /= "" && (all isScriptInfixIdChar nm || isScriptIdFirstChar (head nm) && all isScriptIdChar (tail nm)) = "'" ++ nm-    | otherwise = "'\"" ++ concatMap escape nm ++ "\""-        where escape '\"' = "\\\""-              escape c    = [c]-unparseExprH (CmdName nm)-    | nm == "{"             = "{ "-    | nm == "}"             = " }"-    | all isScriptIdChar nm = nm-    | otherwise             = show nm     -- with quotes-unparseExprH (AppH (AppH (CmdName nm) e1) e2)-    | all isScriptInfixIdChar nm-    = unparseAtom e1 ++ " " ++ nm ++ " " ++ unparseAtom e2-unparseExprH (AppH e1 e2) = unparseExprH e1 ++ " " ++ unparseAtom e2-unparseExprH (CoreH s)    = "[|" ++ s ++ "|]"-unparseExprH (ListH es)   = "[" ++ intercalate "," (map unparseExprH es) ++ "]"--unparseAtom :: ExprH -> String-unparseAtom e@(AppH {}) = "(" ++ unparseExprH e ++ ")"-unparseAtom e           = unparseExprH e------------------------------------------------{-# LINE 1 "templates/GenericTemplate.hs" #-}-{-# LINE 1 "templates/GenericTemplate.hs" #-}-{-# LINE 1 "<built-in>" #-}-{-# LINE 1 "<command-line>" #-}-{-# LINE 1 "templates/GenericTemplate.hs" #-}--- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp --{-# LINE 30 "templates/GenericTemplate.hs" #-}---data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList------{-# LINE 51 "templates/GenericTemplate.hs" #-}--{-# LINE 61 "templates/GenericTemplate.hs" #-}--{-# LINE 70 "templates/GenericTemplate.hs" #-}--infixr 9 `HappyStk`-data HappyStk a = HappyStk a (HappyStk a)---------------------------------------------------------------------------------- starting the parse--happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll---------------------------------------------------------------------------------- Accepting the parse---- If the current token is 0#, it means we've just accepted a partial--- parse (a %partial parser).  We must ignore the saved token on the top of--- the stack in this case.-happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =-	happyReturn1 ans-happyAccept j tk st sts (HappyStk ans _) = -	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)---------------------------------------------------------------------------------- Arrays only: do the next action----happyDoAction i tk st-	= {- nothing -}---	  case action of-		0#		  -> {- nothing -}-				     happyFail i tk st-		-1# 	  -> {- nothing -}-				     happyAccept i tk st-		n | (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}--				     (happyReduceArr Happy_Data_Array.! rule) i tk st-				     where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))-		n		  -> {- nothing -}---				     happyShift new_state i tk st-				     where (new_state) = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))-   where (off)    = indexShortOffAddr happyActOffsets st-         (off_i)  = (off Happy_GHC_Exts.+# i)-	 check  = if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#))-			then (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==#  i)-			else False-         (action)-          | check     = indexShortOffAddr happyTable off_i-          | otherwise = indexShortOffAddr happyDefActions st--{-# LINE 130 "templates/GenericTemplate.hs" #-}---indexShortOffAddr (HappyA# arr) off =-	Happy_GHC_Exts.narrow16Int# i-  where-        i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)-        high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))-        low  = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))-        off' = off Happy_GHC_Exts.*# 2#------data HappyAddr = HappyA# Happy_GHC_Exts.Addr#------------------------------------------------------------------------------------- HappyState data type (not arrays)--{-# LINE 163 "templates/GenericTemplate.hs" #-}---------------------------------------------------------------------------------- Shifting a token--happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =-     let (i) = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in---     trace "shifting the error token" $-     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)--happyShift new_state i tk st sts stk =-     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)---- happyReduce is specialised for the common cases.--happySpecReduce_0 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_0 nt fn j tk st@((action)) sts stk-     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)--happySpecReduce_1 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')-     = let r = fn v1 in-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))--happySpecReduce_2 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')-     = let r = fn v1 v2 in-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))--happySpecReduce_3 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')-     = let r = fn v1 v2 v3 in-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))--happyReduce k i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happyReduce k nt fn j tk st sts stk-     = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of-	 sts1@((HappyCons (st1@(action)) (_))) ->-        	let r = fn stk in  -- it doesn't hurt to always seq here...-       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)--happyMonadReduce k nt fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happyMonadReduce k nt fn j tk st sts stk =-        happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))-       where (sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts))-             drop_stk = happyDropStk k stk--happyMonad2Reduce k nt fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happyMonad2Reduce k nt fn j tk st sts stk =-       happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))-       where (sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts))-             drop_stk = happyDropStk k stk--             (off) = indexShortOffAddr happyGotoOffsets st1-             (off_i) = (off Happy_GHC_Exts.+# nt)-             (new_state) = indexShortOffAddr happyTable off_i-----happyDrop 0# l = l-happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t--happyDropStk 0# l = l-happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs---------------------------------------------------------------------------------- Moving to a new state after a reduction---happyGoto nt j tk st = -   {- nothing -}-   happyDoAction j tk new_state-   where (off) = indexShortOffAddr happyGotoOffsets st-         (off_i) = (off Happy_GHC_Exts.+# nt)-         (new_state) = indexShortOffAddr happyTable off_i------------------------------------------------------------------------------------- Error recovery (0# is the error token)---- parse error if we are in recovery and we fail again-happyFail  0# tk old_st _ stk =---	trace "failing" $ -    	happyError_ tk--{-  We don't need state discarding for our restricted implementation of-    "error".  In fact, it can cause some bogus parses, so I've disabled it-    for now --SDM---- discard a state-happyFail  0# tk old_st (HappyCons ((action)) (sts)) -						(saved_tok `HappyStk` _ `HappyStk` stk) =---	trace ("discarding state, depth " ++ show (length stk))  $-	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))--}---- Enter error recovery: generate an error token,---                       save the old token and carry on.-happyFail  i tk (action) sts stk =---      trace "entering error recovery" $-	happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)---- Internal happy errors:--notHappyAtAll :: a-notHappyAtAll = error "Internal Happy error\n"---------------------------------------------------------------------------------- Hack to get the typechecker to accept our action functions---happyTcHack :: Happy_GHC_Exts.Int# -> a -> a-happyTcHack x y = y-{-# INLINE happyTcHack #-}----------------------------------------------------------------------------------- Seq-ing.  If the --strict flag is given, then Happy emits ---	happySeq = happyDoSeq--- otherwise it emits--- 	happySeq = happyDontSeq--happyDoSeq, happyDontSeq :: a -> b -> b-happyDoSeq   a b = a `seq` b-happyDontSeq a b = b---------------------------------------------------------------------------------- Don't inline any functions from the template.  GHC has a nasty habit--- of deciding to inline happyGoto everywhere, which increases the size of--- the generated parser quite a bit.---{-# NOINLINE happyDoAction #-}-{-# NOINLINE happyTable #-}-{-# NOINLINE happyCheck #-}-{-# NOINLINE happyActOffsets #-}-{-# NOINLINE happyGotoOffsets #-}-{-# NOINLINE happyDefActions #-}--{-# NOINLINE happyShift #-}-{-# NOINLINE happySpecReduce_0 #-}-{-# NOINLINE happySpecReduce_1 #-}-{-# NOINLINE happySpecReduce_2 #-}-{-# NOINLINE happySpecReduce_3 #-}-{-# NOINLINE happyReduce #-}-{-# NOINLINE happyMonadReduce #-}-{-# NOINLINE happyGoto #-}-{-# NOINLINE happyFail #-}---- end of Happy Template.
− dist/build/Language/HERMIT/ParserCore.hs
@@ -1,588 +0,0 @@-{-# OPTIONS_GHC -w #-}-{-# OPTIONS -fglasgow-exts -cpp #-}-{-# LANGUAGE CPP #-}-module Language.HERMIT.ParserCore (parseCore) where--import Control.Monad.Reader-import Data.Char (isSpace, isDigit)--import GhcPlugins--import Language.HERMIT.Context-import Language.HERMIT.External-import Language.HERMIT.Monad-import Language.HERMIT.Primitive.Common-import Language.HERMIT.Syntax (isCoreInfixIdChar, isCoreIdFirstChar, isCoreIdChar)--import Language.KURE.MonadCatch (prefixFailMsg)--import Language.Haskell.TH as TH-import qualified Data.Array as Happy_Data_Array-import qualified GHC.Exts as Happy_GHC_Exts---- parser produced by Happy Version 1.18.6--newtype HappyAbsSyn t4 t5 t6 t7 t8 t9 = HappyAbsSyn HappyAny-#if __GLASGOW_HASKELL__ >= 607-type HappyAny = Happy_GHC_Exts.Any-#else-type HappyAny = forall a . a-#endif-happyIn4 :: t4 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn4 #-}-happyOut4 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t4-happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut4 #-}-happyIn5 :: t5 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn5 #-}-happyOut5 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t5-happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut5 #-}-happyIn6 :: t6 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn6 #-}-happyOut6 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t6-happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut6 #-}-happyIn7 :: t7 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn7 #-}-happyOut7 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t7-happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut7 #-}-happyIn8 :: t8 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn8 #-}-happyOut8 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t8-happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut8 #-}-happyIn9 :: t9 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyIn9 #-}-happyOut9 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> t9-happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOut9 #-}-happyInTok :: (Token) -> (HappyAbsSyn t4 t5 t6 t7 t8 t9)-happyInTok x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyInTok #-}-happyOutTok :: (HappyAbsSyn t4 t5 t6 t7 t8 t9) -> (Token)-happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x-{-# INLINE happyOutTok #-}---happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\xf8\xff\xf8\xff\xf8\xff\x00\x00\x00\x00\x00\x00\x00\x00\xf5\xff\x00\x00\x00\x00\x00\x00\xf0\xff\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00"#--happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\x0b\x00\x18\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#--happyDefActions :: HappyAddr-happyDefActions = HappyA# "\x00\x00\x00\x00\xfe\xff\xfc\xff\xf8\xff\xf7\xff\xf9\xff\x00\x00\xf4\xff\xf6\xff\xf5\xff\x00\x00\x00\x00\xfa\xff\xfd\xff\xfb\xff"#--happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x0c\x00\x0d\x00\x0d\x00\x0c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x1c\x00\x22\x00\x1e\x00\x1c\x00\x20\x00\x1e\x00\xff\xff\x20\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x02\x00\x03\x00\x04\x00\x05\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#--happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x08\x00\x0e\x00\x10\x00\x08\x00\x0c\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x0b\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x09\x00\xff\xff\x0a\x00\x09\x00\x0b\x00\x0a\x00\x00\x00\x0b\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x0e\x00\x04\x00\x05\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#--happyReduceArr = Happy_Data_Array.array (1, 11) [-	(1 , happyReduce_1),-	(2 , happyReduce_2),-	(3 , happyReduce_3),-	(4 , happyReduce_4),-	(5 , happyReduce_5),-	(6 , happyReduce_6),-	(7 , happyReduce_7),-	(8 , happyReduce_8),-	(9 , happyReduce_9),-	(10 , happyReduce_10),-	(11 , happyReduce_11)-	]--happy_n_terms = 35 :: Int-happy_n_nonterms = 6 :: Int--happyReduce_1 = happySpecReduce_1  0# happyReduction_1-happyReduction_1 happy_x_1-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> -	happyIn4-		 (happy_var_1-	)}--happyReduce_2 = happySpecReduce_2  1# happyReduction_2-happyReduction_2 happy_x_2-	happy_x_1-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> -	case happyOut6 happy_x_2 of { happy_var_2 -> -	happyIn5-		 (App happy_var_1 happy_var_2-	)}}--happyReduce_3 = happySpecReduce_1  1# happyReduction_3-happyReduction_3 happy_x_1-	 =  case happyOut6 happy_x_1 of { happy_var_1 -> -	happyIn5-		 (happy_var_1-	)}--happyReduce_4 = happySpecReduce_3  2# happyReduction_4-happyReduction_4 happy_x_3-	happy_x_2-	happy_x_1-	 =  case happyOut4 happy_x_2 of { happy_var_2 -> -	happyIn6-		 (happy_var_2-	)}--happyReduce_5 = happyMonadReduce 2# 2# happyReduction_5-happyReduction_5 (happy_x_2 `HappyStk`-	happy_x_1 `HappyStk`-	happyRest) tk-	 = happyThen (( lookupName "()" Var)-	) (\r -> happyReturn (happyIn6 r))--happyReduce_6 = happySpecReduce_1  2# happyReduction_6-happyReduction_6 happy_x_1-	 =  case happyOut9 happy_x_1 of { happy_var_1 -> -	happyIn6-		 (happy_var_1-	)}--happyReduce_7 = happySpecReduce_1  2# happyReduction_7-happyReduction_7 happy_x_1-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> -	happyIn6-		 (happy_var_1-	)}--happyReduce_8 = happySpecReduce_1  2# happyReduction_8-happyReduction_8 happy_x_1-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> -	happyIn6-		 (happy_var_1-	)}--happyReduce_9 = happyMonadReduce 1# 3# happyReduction_9-happyReduction_9 (happy_x_1 `HappyStk`-	happyRest) tk-	 = happyThen (case happyOutTok happy_x_1 of { (Tinteger happy_var_1) -> -	( mkIntExpr' happy_var_1)}-	) (\r -> happyReturn (happyIn7 r))--happyReduce_10 = happyMonadReduce 1# 4# happyReduction_10-happyReduction_10 (happy_x_1 `HappyStk`-	happyRest) tk-	 = happyThen (case happyOutTok happy_x_1 of { (Tstring happy_var_1) -> -	( lift $ mkStringExpr happy_var_1)}-	) (\r -> happyReturn (happyIn8 r))--happyReduce_11 = happyMonadReduce 1# 5# happyReduction_11-happyReduction_11 (happy_x_1 `HappyStk`-	happyRest) tk-	 = happyThen (case happyOutTok happy_x_1 of { (Tname happy_var_1) -> -	( lookupName happy_var_1 varToCoreExpr)}-	) (\r -> happyReturn (happyIn9 r))--happyNewToken action sts stk [] =-	happyDoAction 34# notHappyAtAll action sts stk []--happyNewToken action sts stk (tk:tks) =-	let cont i = happyDoAction i tk action sts stk tks in-	case tk of {-	Tforall -> cont 1#;-	Trec -> cont 2#;-	Tlet -> cont 3#;-	Tin -> cont 4#;-	Tcase -> cont 5#;-	Tof -> cont 6#;-	Tcast -> cont 7#;-	Tnote -> cont 8#;-	Texternal -> cont 9#;-	Tlocal -> cont 10#;-	Twild -> cont 11#;-	Toparen -> cont 12#;-	Tcparen -> cont 13#;-	Tobrace -> cont 14#;-	Tcbrace -> cont 15#;-	Thash -> cont 16#;-	Teq -> cont 17#;-	Tcolon -> cont 18#;-	Tcoloncolon -> cont 19#;-	Tcoloneqcolon -> cont 20#;-	Tstar -> cont 21#;-	Tarrow -> cont 22#;-	Tlambda -> cont 23#;-	Tat -> cont 24#;-	Tdot -> cont 25#;-	Tquestion -> cont 26#;-	Tsemicolon -> cont 27#;-	Tname happy_dollar_dollar -> cont 28#;-	Tcname happy_dollar_dollar -> cont 29#;-	Tinteger happy_dollar_dollar -> cont 30#;-	Trational happy_dollar_dollar -> cont 31#;-	Tstring happy_dollar_dollar -> cont 32#;-	Tchar happy_dollar_dollar -> cont 33#;-	_ -> happyError' (tk:tks)-	}--happyError_ tk tks = happyError' (tk:tks)--happyThen :: () => CoreParseM a -> (a -> CoreParseM b) -> CoreParseM b-happyThen = (>>=)-happyReturn :: () => a -> CoreParseM a-happyReturn = (return)-happyThen1 m k tks = (>>=) m (\a -> k a tks)-happyReturn1 :: () => a -> b -> CoreParseM a-happyReturn1 = \a tks -> (return) a-happyError' :: () => [(Token)] -> CoreParseM a-happyError' = parseError--parser tks = happySomeParser where-  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))--happySeq = happyDontSeq---mkIntExpr' :: Integer -> CoreParseM CoreExpr-#if __GLASGOW_HASKELL__ > 706-mkIntExpr' i = do-    dflags <- lift getDynFlags-    return $ mkIntExpr dflags i-#else-mkIntExpr' i = return $ mkIntExpr i-#endif--lookupName :: String -> (Id -> CoreExpr) -> CoreParseM CoreExpr-lookupName nm k = do-    c <- ask-    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId (TH.mkName nm) c-    return (k v)--type CoreParseM a = ReaderT HermitC HermitM a--parseError :: Monad m => [Token] -> m a-parseError ts = fail $ "core parse error: " ++ show ts--data Token-    = Tforall-    | Trec-    | Tlet-    | Tin-    | Tcase-    | Tof-    | Tcast-    | Tnote-    | Texternal-    | Tlocal-    | Twild ---    | Toparen ---    | Tcparen ---    | Tobrace-    | Tcbrace-    | Thash-    | Teq-    | Tcolon ---    | Tcoloncolon ---    | Tcoloneqcolon-    | Tstar-    | Tarrow-    | Tlambda ---    | Tat-    | Tdot-    | Tquestion-    | Tsemicolon-    | Tname String-    | Tcname String-    | Tinteger Integer-    | Trational Float-    | Tstring String-    | Tchar Char-    deriving (Eq, Show)--lexer :: String -> Either String [Token]-lexer []           = Right []-lexer ('_' :cs)    = fmap (Twild:)       $ lexer cs-lexer ('(' :cs)    = fmap (Toparen:)     $ lexer cs-lexer (')' :cs)    = fmap (Tcparen:)     $ lexer cs-lexer (':':':':cs) = fmap (Tcoloncolon:) $ lexer cs--- lexer (':' :cs)    = fmap (Tcolon:)      $ lexer cs-lexer ('\\':cs)    = fmap (Tlambda:)     $ lexer cs-lexer ('-':'>':cs) = fmap (Tarrow:)      $ lexer cs-lexer ('\"':cs)    = let (str,rest) = span (/='\"') cs-                     in case rest of-                           ('\"':cs') -> fmap (Tstring str:) $ lexer cs'-                           _          -> Left "lexer: no matching quote"-lexer s@(c:cs) | isSpace           c = lexer cs-               | isDigit           c = let (i,s') = span isDigit s-                                         in fmap (Tinteger (read i):) $ lexer s'-               | isCoreIdFirstChar c = let (i,s') = span isCoreIdChar s-                                         in fmap (Tname i:) $ lexer s'-               | isCoreInfixIdChar c = let (op,s') = span isCoreInfixIdChar s-                                         in fmap (Tname op:) $ lexer s'-lexer s            = Left $ "lexer: no match on " ++ s-------------------------------------------------parseCore :: CoreString -> HermitC -> HermitM CoreExpr-parseCore (CoreString s) c =-    case lexer s of-        Left msg -> fail msg-        Right tokens -> runReaderT (parser tokens) c-{-# LINE 1 "templates/GenericTemplate.hs" #-}-{-# LINE 1 "templates/GenericTemplate.hs" #-}-{-# LINE 1 "<built-in>" #-}-{-# LINE 1 "<command-line>" #-}-{-# LINE 1 "templates/GenericTemplate.hs" #-}--- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp --{-# LINE 30 "templates/GenericTemplate.hs" #-}---data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList------{-# LINE 51 "templates/GenericTemplate.hs" #-}--{-# LINE 61 "templates/GenericTemplate.hs" #-}--{-# LINE 70 "templates/GenericTemplate.hs" #-}--infixr 9 `HappyStk`-data HappyStk a = HappyStk a (HappyStk a)---------------------------------------------------------------------------------- starting the parse--happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll---------------------------------------------------------------------------------- Accepting the parse---- If the current token is 0#, it means we've just accepted a partial--- parse (a %partial parser).  We must ignore the saved token on the top of--- the stack in this case.-happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =-	happyReturn1 ans-happyAccept j tk st sts (HappyStk ans _) = -	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)---------------------------------------------------------------------------------- Arrays only: do the next action----happyDoAction i tk st-	= {- nothing -}---	  case action of-		0#		  -> {- nothing -}-				     happyFail i tk st-		-1# 	  -> {- nothing -}-				     happyAccept i tk st-		n | (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}--				     (happyReduceArr Happy_Data_Array.! rule) i tk st-				     where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))-		n		  -> {- nothing -}---				     happyShift new_state i tk st-				     where (new_state) = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))-   where (off)    = indexShortOffAddr happyActOffsets st-         (off_i)  = (off Happy_GHC_Exts.+# i)-	 check  = if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#))-			then (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==#  i)-			else False-         (action)-          | check     = indexShortOffAddr happyTable off_i-          | otherwise = indexShortOffAddr happyDefActions st--{-# LINE 130 "templates/GenericTemplate.hs" #-}---indexShortOffAddr (HappyA# arr) off =-	Happy_GHC_Exts.narrow16Int# i-  where-        i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)-        high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))-        low  = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))-        off' = off Happy_GHC_Exts.*# 2#------data HappyAddr = HappyA# Happy_GHC_Exts.Addr#------------------------------------------------------------------------------------- HappyState data type (not arrays)--{-# LINE 163 "templates/GenericTemplate.hs" #-}---------------------------------------------------------------------------------- Shifting a token--happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =-     let (i) = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in---     trace "shifting the error token" $-     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)--happyShift new_state i tk st sts stk =-     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)---- happyReduce is specialised for the common cases.--happySpecReduce_0 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_0 nt fn j tk st@((action)) sts stk-     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)--happySpecReduce_1 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')-     = let r = fn v1 in-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))--happySpecReduce_2 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')-     = let r = fn v1 v2 in-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))--happySpecReduce_3 i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')-     = let r = fn v1 v2 v3 in-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))--happyReduce k i fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happyReduce k nt fn j tk st sts stk-     = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of-	 sts1@((HappyCons (st1@(action)) (_))) ->-        	let r = fn stk in  -- it doesn't hurt to always seq here...-       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)--happyMonadReduce k nt fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happyMonadReduce k nt fn j tk st sts stk =-        happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))-       where (sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts))-             drop_stk = happyDropStk k stk--happyMonad2Reduce k nt fn 0# tk st sts stk-     = happyFail 0# tk st sts stk-happyMonad2Reduce k nt fn j tk st sts stk =-       happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))-       where (sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts))-             drop_stk = happyDropStk k stk--             (off) = indexShortOffAddr happyGotoOffsets st1-             (off_i) = (off Happy_GHC_Exts.+# nt)-             (new_state) = indexShortOffAddr happyTable off_i-----happyDrop 0# l = l-happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t--happyDropStk 0# l = l-happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs---------------------------------------------------------------------------------- Moving to a new state after a reduction---happyGoto nt j tk st = -   {- nothing -}-   happyDoAction j tk new_state-   where (off) = indexShortOffAddr happyGotoOffsets st-         (off_i) = (off Happy_GHC_Exts.+# nt)-         (new_state) = indexShortOffAddr happyTable off_i------------------------------------------------------------------------------------- Error recovery (0# is the error token)---- parse error if we are in recovery and we fail again-happyFail  0# tk old_st _ stk =---	trace "failing" $ -    	happyError_ tk--{-  We don't need state discarding for our restricted implementation of-    "error".  In fact, it can cause some bogus parses, so I've disabled it-    for now --SDM---- discard a state-happyFail  0# tk old_st (HappyCons ((action)) (sts)) -						(saved_tok `HappyStk` _ `HappyStk` stk) =---	trace ("discarding state, depth " ++ show (length stk))  $-	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))--}---- Enter error recovery: generate an error token,---                       save the old token and carry on.-happyFail  i tk (action) sts stk =---      trace "entering error recovery" $-	happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)---- Internal happy errors:--notHappyAtAll :: a-notHappyAtAll = error "Internal Happy error\n"---------------------------------------------------------------------------------- Hack to get the typechecker to accept our action functions---happyTcHack :: Happy_GHC_Exts.Int# -> a -> a-happyTcHack x y = y-{-# INLINE happyTcHack #-}----------------------------------------------------------------------------------- Seq-ing.  If the --strict flag is given, then Happy emits ---	happySeq = happyDoSeq--- otherwise it emits--- 	happySeq = happyDontSeq--happyDoSeq, happyDontSeq :: a -> b -> b-happyDoSeq   a b = a `seq` b-happyDontSeq a b = b---------------------------------------------------------------------------------- Don't inline any functions from the template.  GHC has a nasty habit--- of deciding to inline happyGoto everywhere, which increases the size of--- the generated parser quite a bit.---{-# NOINLINE happyDoAction #-}-{-# NOINLINE happyTable #-}-{-# NOINLINE happyCheck #-}-{-# NOINLINE happyActOffsets #-}-{-# NOINLINE happyGotoOffsets #-}-{-# NOINLINE happyDefActions #-}--{-# NOINLINE happyShift #-}-{-# NOINLINE happySpecReduce_0 #-}-{-# NOINLINE happySpecReduce_1 #-}-{-# NOINLINE happySpecReduce_2 #-}-{-# NOINLINE happySpecReduce_3 #-}-{-# NOINLINE happyReduce #-}-{-# NOINLINE happyMonadReduce #-}-{-# NOINLINE happyGoto #-}-{-# NOINLINE happyFail #-}---- end of Happy Template.
driver/Main.hs view
@@ -1,4 +1,4 @@--- Simple driver for hermit+{-# LANGUAGE ViewPatterns #-}  module Main where @@ -8,7 +8,7 @@ import System.Process import System.Exit -import Data.List (isPrefixOf)+import Data.List (isPrefixOf, partition) import System.Directory (doesFileExist)  usage :: IO ()@@ -29,6 +29,11 @@         ,""         ,"HERMIT_ARGS"         ,"  -opt=MODULE : where MODULE is the module containing a HERMIT optimization plugin"+        ,"  -vN         : controls verbosity, where N is one of the following values:"+        ,"                  0 : suppress HERMIT messages, pass -v0 to GHC"+        ,"                  1 : suppress HERMIT messages"+        ,"                  2 : pass -v0 to GHC"+        ,"                  3 : (default) display all HERMIT and GHC messages"         ,""         ,"MOD_ARGS"         ,"  SCRIPTNAME : name of script file to run for this module"@@ -70,7 +75,7 @@                     [ "-fplugin-opt=" ++ pluginName ++ ":" ++ m_nm ++ ":" ++ opt                     | (m_nm, m_opts) <- module_args                     , opt <- "" : m_opts-                    ] ++ ghc_args+                    ] ++ extraGHCArgs hermit_args' ++ ghc_args         putStrLn $ "% ghc " ++ unwords cmds         (_,_,_,r) <- createProcess $ proc "ghc" cmds         ex <- waitForProcess r@@ -81,3 +86,13 @@     where go plug flags [] = (plug, flags)           go plug flags (f:fs) | "-opt=" `isPrefixOf` f = go (drop 5 f) flags fs                                | otherwise              = go plug (f:flags) fs++-- | See if the given HERMIT args imply any additional GHC args+extraGHCArgs :: [String] -> [String]+extraGHCArgs (matchArgs (`elem` ["-v0","-v2"]) -> Just (_,r)) = "-v0" : extraGHCArgs r+extraGHCArgs _ = []++matchArgs :: (String -> Bool) -> [String] -> Maybe ([String], [String])+matchArgs p args = case partition p args of+                    ([],_) -> Nothing+                    (as,r) -> Just (as,r)
− examples/WWSplitTactic.hss
@@ -1,18 +0,0 @@-{-fix-intro-consider lam-let-intro 'f-up-let-float-arg-1-apply-rule ww-simplify-{ 1; let-intro 'w }-let-float-arg-{ rhs-of 'w-  unfold 'fix ; alpha-let ['work]-  simplify-}-let-subst-let-float-arg-}
examples/concatVanishes/ConcatVanishes.hss view
@@ -1,6 +1,15 @@-ww-split-param 1 [|wrap|] [|unwrap|]-any-call (unfold 'wrap)-one-td (unfold 'unwrap)-innermost (case-float-let >+> bash >+> push 'repH >+> unfold-rule "repH ++" >+> unfold-rule "repH (:)" >+> unfold-rule "repH []" >+> unfold-rule "[] ++" >+> unfold-rule "[] ++" >+> unfold-rule "(:) ++")-any-td (unfold-rule "rep-abs-fusion")-any-call (unfold 'absH)+load-as-rewrite "WWA" "WW-Ass-A.hss"+define-rewrite "WWC" "ww-result-AssA-to-AssC WWA"+load-as-rewrite "StrictRepH" "StrictRepH.hss"++run-script "do-the-ww-split" -- ugly hack because we lack paramaterisable scripts++bash+{ rhs-of 'work+  lam-body+  eta-expand 'acc+  lam-body+  bash-extended-with [ push 'repH StrictRepH, forward ww-result-fusion, apply-rules ["repH ++","repH (:)","repH []"] ]+  try (bash-extended-with [push-unsafe 'work])+}+one-td (unfold 'absH)
examples/concatVanishes/Flatten.hs view
@@ -5,16 +5,9 @@  data Tree a = Node (Tree a) (Tree a) | Leaf a -unwrap :: (Tree a -> [a]) -> (Tree a -> H a)-unwrap f = repH . f--wrap :: (Tree a -> H a) -> (Tree a -> [a])-wrap g = absH . g- flatten :: Tree a -> [a] flatten (Leaf a)   = [a] flatten (Node l r) = flatten l ++ flatten r  main :: IO () main = print (flatten (Node (Leaf 'h') (Leaf 'i')))-
examples/concatVanishes/Flatten.hss view
@@ -1,3 +1,2 @@-flatten-module-consider 'flatten-{ load "ConcatVanishes.hss" }+define-script "do-the-ww-split" "binding-of 'flatten ; ww-result-split-static-arg 1 [0] [| absH |] [| repH |] WWC"+load-and-run "ConcatVanishes.hss"
examples/concatVanishes/HList.hs view
@@ -14,15 +14,11 @@ absH :: H a -> [a] absH f = f [] +-- Should be in the "List" module+{-# RULES "++ []"  forall xs .  xs ++ [] = xs #-}+{-# RULES "++ strict"           (++) undefined = undefined #-}+ -- The "Algebra" for repH {-# RULES "repH ++" forall xs ys .     repH (xs ++ ys) = repH xs . repH ys #-} {-# RULES "repH []" 	               repH [] = id                        #-} {-# RULES "repH (:)" forall x xs .     repH (x:xs) = ((:) x) . repH xs     #-}---- Should be in the "List" module-{-# RULES "(:) ++" forall x xs ys .    (x:xs) ++ ys = x : (xs ++ ys)       #-}-{-# RULES "[] ++"  forall xs .         [] ++ xs     = xs                   #-}-{-# RULES "++ []"  forall xs .         xs ++ []     = xs                   #-}---- has preconditon-{-# RULES "rep-abs-fusion" forall h .  repH (absH h) = h                   #-}
examples/concatVanishes/QSort.hs view
@@ -6,12 +6,6 @@  data Tree a = Node (Tree a) (Tree a) | Leaf a -unwrap   :: ([a] -> [a]) -> ([a] -> H a)-unwrap f = repH . f--wrap   :: ([a] -> H a) -> ([a] -> [a])-wrap g = absH . g- qsort        :: Ord a => [a] -> [a] qsort []     = [] qsort (a:as) = qsort bs ++ [a] ++ qsort cs
examples/concatVanishes/QSort.hss view
@@ -1,5 +1,2 @@-flatten-module-consider 'qsort-{ load "ConcatVanishes.hss" }-one-td let-subst-bash+define-script "do-the-ww-split" "binding-of 'qsort ; ww-result-split-static-arg 2 [0] [| absH |] [| repH |] WWC"+load-and-run "ConcatVanishes.hss"
examples/concatVanishes/Rev.hs view
@@ -3,12 +3,6 @@ import HList import Data.Function (fix) -unwrap :: ([a] -> [a]) -> ([a] -> H a)-unwrap f = repH . f--wrap :: ([a] -> H a) -> ([a] -> [a])-wrap g = absH . g- rev :: [a] -> [a] rev []     = [] rev (y:ys) = rev ys ++ [y]
examples/concatVanishes/Rev.hss view
@@ -1,4 +1,2 @@-flatten-module-consider 'rev-{ load "ConcatVanishes.hss" }-+define-script "do-the-ww-split" "binding-of 'rev ; ww-result-split-static-arg 1 [0] [| absH |] [| repH |] WWC"+load-and-run "ConcatVanishes.hss"
examples/evaluation/Eval.hs view
@@ -1,6 +1,7 @@ module Main where -import Data.Function(fix)+import Prelude hiding (abs)+import Data.Function (fix)  data Expr = Val Int | Add Expr Expr | Throw | Catch Expr Expr @@ -18,13 +19,13 @@                                     Nothing -> Nothing                                     Just n  -> Just (m + n) -unwrap :: (Expr -> Mint) -> Expr -> (Int -> Mint) -> Mint -> Mint-unwrap g e s f = case g e of-                   Nothing -> f-                   Just n  -> s n+abs :: ((Int -> Mint) -> Mint -> Mint) -> Mint+abs h = h Just Nothing -wrap :: (Expr -> (Int -> Mint) -> Mint -> Mint) -> Expr -> Mint-wrap h e = h e Just Nothing+rep :: Mint -> (Int -> Mint) -> Mint -> Mint+rep mn s f = case mn of+               Nothing -> f+               Just n  -> s n  main :: IO () main = print (eval $ Val 5)
examples/evaluation/Eval.hss view
@@ -1,19 +1,23 @@+load-as-rewrite "WWA" "WW-Ass-A.hss" flatten-module-consider 'eval-ww-split [| wrap |] [| unwrap |]-{rhs-of 'work-   eta-expand 'e ; lam-body-   eta-expand 's ; lam-body-   eta-expand 'f ; lam-body-   unfold 'unwrap-   one-td (unfold 'f)-   bash-   {-     consider case ; [case-alt 1, alt-rhs] ; abstract 'm-     consider case ; [case-alt 1, alt-rhs] ; abstract 'n-   }-   any-bu (fold 'unwrap)-   any-bu (foreward (ww-fusion [| wrap |] [|unwrap|] [|work|]))+binding-of 'eval+ww-result-split [| abs |] [| rep |] (ww-result-AssA-to-AssC WWA)+{ def-rhs+  let-subst+  { let-body+    alpha-lam 'e+    lam-body+    unfold 'abs+  }+  { rhs-of 'work+    alpha-lam 'e ; lam-body+    unfold 'rep+    bash+    [lam-body, lam-body]+    { consider case ; [ case-alt 1, alt-rhs ] ; abstract 'm+      consider case ; [ case-alt 1, alt-rhs ] ; abstract 'n+    }+    any-bu (fold 'rep)+    any-td (forward ww-result-fusion)+  } }-simplify-any-call (unfold 'wrap)
examples/factorial/Fac.hs view
@@ -6,6 +6,8 @@ import GHC.Exts import Data.Function(fix) +------------------------------------+ fac :: Int -> Int fac 0 = 1 fac n = n * fac (n -1)@@ -26,3 +28,5 @@  (-) :: Int -> Int -> Int (I# x) - (I# y) = I# (x -# y)++------------------------------------
examples/factorial/Fac.hss view
@@ -1,22 +1,7 @@+load-as-rewrite "WWA" "WW-Ass-A.hss" flatten-module-consider 'fac-ww-split [| wrap |] [| unwrap |]-{rhs-of 'work-  eta-expand 'x-  one-td (unfold 'unwrap)-  one-td (unfold 'f)-  one-td (unfold 'wrap)-  simplify-  {-    consider alt ; alt-rhs ; case-float-arg-    consider alt ; alt-rhs ; case-float-arg-  }-  one-td (unfold '-)-  one-td (unfold '*)-  simplify-  innermost case-float-case-}-simplify-innermost (case-float <+ case-reduce)-simplify-{ [def-rhs, let-body] ; eta-expand 'n ; any-call (unfold 'wrap) }+binding-of 'fac+ww-split [| wrap |] [| unwrap |] (ww-AssA-to-AssC WWA)+bash-extended-with [ case-elim-inline-scrutinee , inline [ 'unwrap, 'wrap, '*, '- ] ]++{ [def-rhs, let-body] ; alpha-lam 'n } -- cosmetic
examples/fib-stream/Fib.hss view
@@ -1,7 +1,7 @@ flatten-module consider 'fib {-  ww-split [| wrap Nat |] [| unwrap Nat |]+  ww-split-unsafe [| wrap Nat |] [| unwrap Nat |]   {rhs-of 'work     unfold 'unwrap     any-call (unfold 'f)
examples/fib-tuple/Fib.hs view
@@ -33,7 +33,7 @@ --                         in (y,x+y)  wrap :: (Nat -> (Nat, Nat)) -> Nat -> Nat-wrap h = fst . h+wrap h n = fst (h n)  unwrap :: (Nat -> Nat) -> Nat -> (Nat, Nat) unwrap h n = (h n, h (S n))
examples/fib-tuple/Fib.hss view
@@ -1,10 +1,12 @@+load-as-rewrite "WWA" "WW-Ass-A.hss" flatten-module-consider 'fib +binding-of 'fib+ { -ww-split [| wrap |] [| unwrap |]-consider 'work ; remember origwork+ww-split [| wrap |] [| unwrap |] (ww-AssA-to-AssC WWA)+binding-of 'work ; remember origwork  -- work = unwrap (f (wrap work)) @@ -34,7 +36,7 @@ -- work 0     = (0, 1) -- work (n+1) = (f (wrap work) (n+1), wrap (unwrap (f (wrap work))) (n+1) + wrap (unwrap (f (wrap work))) n) -any-bu (foreward (ww-assumption-A [| wrap |] [| unwrap |]))+any-bu (forward (ww-assumption-A [| wrap |] [| unwrap |] WWA ))  -- work 0     = (0, 1) -- work (n+1) = (f (wrap work) (n+1), f (wrap work) (n+1) + f (wrap work) n)@@ -61,7 +63,6 @@  } -innermost dead-let-elimination any-call (unfold 'wrap) simplify 
examples/flatten/Flatten.hs view
@@ -5,16 +5,9 @@  data Tree a = Node (Tree a) (Tree a) | Leaf a -unwrap :: (Tree a -> [a]) -> (Tree a -> H a)-unwrap f = repH . f--wrap :: (Tree a -> H a) -> (Tree a -> [a])-wrap g = absH . g- flatten :: Tree a -> [a] flatten (Leaf a)   = [a] flatten (Node l r) = flatten l ++ flatten r  main :: IO () main = print (flatten (Node (Leaf 'h') (Leaf 'i')))-
examples/flatten/Flatten.hss view
@@ -1,20 +1,14 @@-flatten-module-consider 'flatten-ww-split-param 1 [|wrap|] [|unwrap|]+load-as-rewrite "WWA" "WW-Ass-A.hss"+define-rewrite "WWC" "ww-result-AssA-to-AssC WWA"+load-as-rewrite "StrictRepH" "StrictRepH.hss"+binding-of 'flatten+ww-result-split-static-arg 1 [0] [| absH |] [| repH |] WWC bash-{consider lam ; alpha-lam 't}-any-call (unfold 'wrap)-any-call (unfold 'unwrap)-simplify-{rhs-of 'work-   lam-body-   eta-expand 'acc-   innermost case-float-   any-call (unfold-rule "repH ++")-   one-td (foreward (ww-fusion [| absH t |] [| repH t |] [| work l |]))-   one-td (foreward (ww-fusion [| absH t |] [| repH t |] [| work r |]))-   any-call (unfold-rule "repH (:)")-   any-call (unfold-rule "repH []")-   simplify+{ rhs-of 'work+  alpha-lam 'tree+  lam-body+  eta-expand 'acc+  lam-body+  bash-extended-with [push 'repH StrictRepH, forward ww-result-fusion, apply-rules ["repH ++", "repH (:)", "repH []"] ] }-any-call (unfold 'absH)+one-td (unfold 'absH)
examples/flatten/HList.hs view
@@ -14,6 +14,10 @@ absH :: H a -> [a] absH f = f [] +-- Should be in a "List" module+{-# RULES "++ []"  forall xs .  xs ++ [] = xs #-}+{-# RULES "++ strict"           (++) undefined = undefined #-}+ -- The "Algebra" for repH {-# RULES "repH ++" forall xs ys   . repH (xs ++ ys) = repH xs . repH ys #-} {-# RULES "repH []" 	             repH [] = id  	       	         #-}
examples/hanoi/Hanoi.hss view
@@ -2,9 +2,9 @@  -- do the w/w split consider 'hanoi-{ ww-split [| wrap |] [| unwrap |] }+{ ww-split-unsafe [| wrap |] [| unwrap |] } -{ consider 'work+{ binding-of 'work   remember origwork    any-call (unfold 'unwrap)@@ -18,7 +18,7 @@   { [case-alt 1, alt-rhs] ; case-split-inline 'a     { case-alt 0 ; any-call (unfold 'f) ; simplify       any-call (unfold origwork)-      any-call (foreward (ww-assumption-A [| wrap |] [| unwrap |]))+      any-call (forward (ww-assumption-A-unsafe [| wrap |] [| unwrap |]))       any-call (unfold 'f)       simplify       any-call (unfold-rule "[] ++")@@ -27,13 +27,13 @@     { case-alt 1 ; any-call (unfold 'f) ; simplify        any-call (unfold origwork)-      any-call (foreward (ww-assumption-A [| wrap |] [| unwrap |]))+      any-call (forward (ww-assumption-A-unsafe [| wrap |] [| unwrap |]))       any-call (unfold 'f)       innermost let-subst ; simplify        -- recursion decrements by two, so must do this again       any-call (unfold origwork)-      any-call (foreward (ww-assumption-A [| wrap |] [| unwrap |]))+      any-call (forward (ww-assumption-A-unsafe [| wrap |] [| unwrap |]))        -- time to let intro       -- need a "occurance 'work" like consider@@ -57,4 +57,4 @@     }   } }-innermost dead-let-elimination+innermost let-elim
examples/last/Last.hs view
@@ -3,17 +3,21 @@ import Data.Function(fix) import Prelude hiding (last) +-------------------------------------------------+ unwrap         :: ([a] -> a) -> a -> [a] -> a unwrap f a as  = f (a:as)  wrap           :: (a -> [a] -> a) -> [a] -> a-wrap f []      = error "wrap _ []"+wrap f []      = undefined wrap f (a:as)  = f a as  last           :: [a] -> a-last []        = error "last []"+last []        = undefined last [a]       = a last (_:a:as)  = last (a:as)  main :: IO () main = print (last "hello")++-------------------------------------------------
examples/last/Last.hss view
@@ -1,17 +1,7 @@+load-as-rewrite "WWB" "WW-Ass-B.hss"+define-rewrite "WWC" "ww-AssB-to-AssC WWB" flatten-module-consider 'last-ww-split-param 1 [|wrap|] [|unwrap|]-{rhs-of 'work-   eta-expand 'b-   lam-body-   eta-expand 'bs-   lam-body-   unfold 'unwrap-   unfold 'f-   bash-   consider app-   unfold 'wrap-   bash-}-any-call (unfold 'wrap)-bash+binding-of 'last+ww-split-static-arg 1 [0] [| wrap |] [| unwrap |] WWC+bash-extended-with [ inline [ 'f, 'wrap, 'unwrap ] ]+unshadow
examples/mean/Mean.hss view
@@ -7,9 +7,9 @@   { case-expr ; abstract 'xs ; app-fun ; let-intro 'sumlength } } innermost let-float-consider 'sumlength+binding-group-of 'sumlength nonrec-to-rec           -- since we intend sumlength to be a recursive function-rec-def 0+binding-of 'sumlength remember sumlen { [def-rhs, lam-body]   case-split-inline 'xs
examples/qsort/HList.hs view
@@ -14,12 +14,11 @@ absH :: H a -> [a] absH f = f [] +-- Should be in a "List" module+{-# RULES "++ []"  forall xs .  xs ++ [] = xs #-}+{-# RULES "++ strict"           (++) undefined = undefined #-}+ -- The "Algebra" for repH {-# RULES "repH ++" forall xs ys   . repH (xs ++ ys) = repH xs . repH ys #-} {-# RULES "repH []" 	             repH [] = id  	       	         #-} {-# RULES "repH (:)" forall x xs   . repH (x:xs) = ((:) x) . repH xs     #-}-----
examples/qsort/QSort.hs view
@@ -6,12 +6,6 @@  data Tree a = Node (Tree a) (Tree a) | Leaf a -unwrap :: ([a] -> [a]) -> ([a] -> H a)-unwrap f = repH . f--wrap :: ([a] -> H a) -> ([a] -> [a])-wrap g = absH . g- qsort :: Ord a => [a] -> [a] qsort []     = [] qsort (a:as) = qsort bs ++ [a] ++ qsort cs@@ -20,4 +14,3 @@  main :: IO () main = print (qsort [8,3,5,7,2,9,4,6,3,2])-
examples/qsort/QSort.hss view
@@ -1,34 +1,15 @@-flatten-module-consider 'qsort-ww-split-param 1 [|wrap|] [|unwrap|]+load-as-rewrite "WWA" "WW-Ass-A.hss"+define-rewrite "WWC" "ww-result-AssA-to-AssC WWA"+load-as-rewrite "StrictRepH" "StrictRepH.hss"+binding-of 'qsort+ww-result-split-static-arg 2 [0] [| absH |] [| repH |] WWC bash-{consider lam ; alpha-lam 't}-any-call (unfold 'wrap)-any-call (unfold 'unwrap)-simplify-{rhs-of 'work+{ rhs-of 'work   alpha-lam 'xs   lam-body-  any-td case-float-arg   eta-expand 'acc-  bash-  one-td inline-case-binder -- this used to be part of bash-  bash   lam-body-  {  case-alt 1-     any-td (push 'repH)-     consider alt-     alpha-alt ['bs,'cs]-     any-td (unfold-rule "repH ++")-     any-bu case-float-arg-     simplify-     one-td (foreward (ww-fusion [| absH t |] [| repH t |] [| work bs |]))-     one-td (foreward (ww-fusion [| absH t |] [| repH t |] [| work cs |]))-     any-call (unfold-rule "repH (:)")-     simplify-  }-  any-call (unfold-rule "repH []")-  any-call (unfold 'id)+  bash-extended-with [push 'repH StrictRepH, forward ww-result-fusion, apply-rules ["repH ++", "repH (:)", "repH []"] ]+  bash-extended-with [push-unsafe 'work] } one-td (unfold 'absH)-
examples/reverse/HList.hs view
@@ -14,12 +14,11 @@ absH :: H a -> [a] absH f = f [] +-- Should be in a "List" module+{-# RULES "++ []"  forall xs .  xs ++ [] = xs #-}+{-# RULES "++ strict"           (++) undefined = undefined #-}+ -- The "Algebra" for repH {-# RULES "repH ++" forall xs ys   . repH (xs ++ ys) = repH xs . repH ys #-} {-# RULES "repH []" 	             repH [] = id  	       	         #-} {-# RULES "repH (:)" forall x xs   . repH (x:xs) = ((:) x) . repH xs     #-}-----
examples/reverse/Reverse.hs view
@@ -1,13 +1,9 @@ module Main where  import HList-import Data.Function (fix)--unwrap :: ([a] -> [a]) -> ([a] -> H a)-unwrap f = repH . f+-- import Seq -wrap :: ([a] -> H a) -> ([a] -> [a])-wrap g = absH . g+import Data.Function (fix)  rev :: [a] -> [a] rev []     = []
examples/reverse/Reverse.hss view
@@ -1,21 +1,14 @@-flatten-module-consider 'rev-ww-split-param 1 [|wrap|] [|unwrap|]+load-as-rewrite "WWA" "WW-Ass-A.hss"+define-rewrite "WWC" "ww-result-AssA-to-AssC WWA"+load-as-rewrite "StrictRepH" "StrictRepH.hss"+binding-of 'rev+ww-result-split-static-arg 1 [0] [| absH |] [| repH |] WWC bash-{consider lam ; alpha-lam 't}-any-call (unfold 'wrap)-any-call (unfold 'unwrap)-simplify-{rhs-of 'work-   alpha-lam 'ys-   lam-body-   eta-expand 'acc-   innermost case-float-   one-td (unfold-rule "repH ++")-   one-td (foreward (ww-fusion [| absH t |] [| repH t |] [| work xs |]))-   any-call (unfold-rule "repH (:)")-   simplify-   any-call (unfold-rule "repH []")-   any-call (unfold 'id)+{ rhs-of 'work+  alpha-lam 'ys+  lam-body+  eta-expand 'acc+  lam-body+  bash-extended-with [push 'repH StrictRepH, forward ww-result-fusion, apply-rules ["repH ++", "repH (:)", "repH []"] ] }-any-call (unfold 'absH)+one-td (unfold 'absH)
hermit.cabal view
@@ -1,5 +1,5 @@ Name:                hermit-Version:             0.2.0.0+Version:             0.3.0.0 Synopsis:            Haskell Equational Reasoning Model-to-Implementation Tunnel Description:   HERMIT uses Haskell to express semi-formal models,@@ -8,22 +8,16 @@   these models and implementations. The key transformation   in the bridging DSL is the worker/wrapper transformation.   .-  This is a pre-alpha `please give feedback' release.+  This is an alpha `please give feedback' release.   Shortcomings/gotchas include:   .     * Command line completion is ad hoc at the moment.   .     * log command prints linearly, even if command history is a tree.   .-    * The fold rewrite can only fold syntactically alpha-equivalent (up to-      parameters of the function you are folding) expressions.-  .     * RULES have issues with forall types.   .-    * Different core comes out depending on whether you ascribe explicit-      type signatures.-  .-    * A number of rewrites don't enforce preconditions. ex: cast elimination+    * A number of rewrites don't enforce preconditions. eg: cast elimination       always works, even if the cast is necessary   .   Examples can be found in the examples sub-directory.@@ -36,12 +30,12 @@   .   @    $ hermit Reverse.hs Reverse.hss resume-   [starting HERMIT v0.2.0.0 on Reverse.hs]+   [starting HERMIT v0.3.0.0 on Reverse.hs]    % ghc Reverse.hs -fforce-recomp -O2 -dcore-lint -fexpose-all-unfoldings -fsimple-list-literals -fplugin=HERMIT -fplugin-opt=HERMIT:Main:Reverse.hss -fplugin-opt=HERMIT:Main:resume    [1 of 2] Compiling HList            ( HList.hs, HList.o )    Loading package ghc-prim ... linking ... done.    ...-   Loading package hermit-0.2.0.0 ... linking ... done.+   Loading package hermit-0.3.0.0 ... linking ... done.    [2 of 2] Compiling Main             ( Reverse.hs, Reverse.o )    Linking Reverse ...    $ ./Reverse@@ -52,12 +46,12 @@   .   @    $ hermit Reverse.hs-   [starting HERMIT v0.2.0.0 on Reverse.hs]+   [starting HERMIT v0.3.0.0 on Reverse.hs]    % ghc Reverse.hs -fforce-recomp -O2 -dcore-lint -fexpose-all-unfoldings -fsimple-list-literals -fplugin=HERMIT -fplugin-opt=HERMIT:Main:    [1 of 2] Compiling HList            ( HList.hs, HList.o )    Loading package ghc-prim ... linking ... done.    ...-   Loading package hermit-0.2.0.0 ... linking ... done.+   Loading package hermit-0.3.0.0 ... linking ... done.    [2 of 2] Compiling Main             ( Reverse.hs, Reverse.o )    ===================== Welcome to HERMIT =====================    HERMIT is a toolkit for the interactive transformation of GHC@@ -104,12 +98,11 @@ License-file:        LICENSE Author:              Andrew Farmer, Andy Gill, Ed Komp, Neil Sculthorpe Maintainer:          Andy Gill <andygill@ku.edu>-Stability:           pre-alpha+Stability:           alpha build-type:          Simple Cabal-Version:       >= 1.14  extra-source-files:-    examples/WWSplitTactic.hss     examples/concatVanishes/ConcatVanishes.hss     examples/concatVanishes/Flatten.hs     examples/concatVanishes/Flatten.hss@@ -153,63 +146,82 @@                  data-default >= 0.5.0,                  ghc >= 7.6,                  haskeline >= 0.7.0.3,-                 kure >= 2.7.1,+                 kure >= 2.14.0,                  marked-pretty >= 0.1,                  mtl >= 2.1.2,                  operational >= 0.2.2.1,+                 process >= 1.1.0.2,                  stm >= 2.4,                  template-haskell >= 2.8.0.0,+                 temporary >= 1.1.2.4,+                 terminfo >= 0.3.2.5,                  transformers    default-language: Haskell2010    Exposed-modules:        HERMIT-       HERMIT.Driver -       Language.HERMIT.Context-       Language.HERMIT.Core-       Language.HERMIT.Dictionary-       Language.HERMIT.External-       Language.HERMIT.GHC-       Language.HERMIT.Interp-       Language.HERMIT.Kernel-       Language.HERMIT.Kernel.Scoped-       Language.HERMIT.Kure-       Language.HERMIT.Kure.SumTypes-       Language.HERMIT.Monad-       Language.HERMIT.Optimize-       Language.HERMIT.Parser-       Language.HERMIT.ParserCore+       HERMIT.Context+       HERMIT.Core+       HERMIT.Dictionary+       HERMIT.Driver -       Language.HERMIT.Plugin+       HERMIT.Dictionary.AlphaConversion+       HERMIT.Dictionary.Common+       HERMIT.Dictionary.Composite+       HERMIT.Dictionary.Debug+       HERMIT.Dictionary.FixPoint+       HERMIT.Dictionary.Fold+       HERMIT.Dictionary.Function+       HERMIT.Dictionary.GHC+       HERMIT.Dictionary.Inline+       HERMIT.Dictionary.Kure+       HERMIT.Dictionary.Local+       HERMIT.Dictionary.Local.Bind+       HERMIT.Dictionary.Local.Case+       HERMIT.Dictionary.Local.Cast+       HERMIT.Dictionary.Local.Let+       HERMIT.Dictionary.Navigation+       HERMIT.Dictionary.Navigation.Crumbs+       HERMIT.Dictionary.New+       HERMIT.Dictionary.Query+       HERMIT.Dictionary.Reasoning+       HERMIT.Dictionary.Undefined+       HERMIT.Dictionary.Unfold+       HERMIT.Dictionary.Unsafe+       HERMIT.Dictionary.WorkerWrapper.Common+       HERMIT.Dictionary.WorkerWrapper.Fix+       HERMIT.Dictionary.WorkerWrapper.FixResult -       Language.HERMIT.Primitive.AlphaConversion-       Language.HERMIT.Primitive.Common-       Language.HERMIT.Primitive.Debug-       Language.HERMIT.Primitive.FixPoint-       Language.HERMIT.Primitive.Fold-       Language.HERMIT.Primitive.GHC-       Language.HERMIT.Primitive.Inline-       Language.HERMIT.Primitive.Kure-       Language.HERMIT.Primitive.Local-       Language.HERMIT.Primitive.Local.Let-       Language.HERMIT.Primitive.Local.Case-       Language.HERMIT.Primitive.Local.Cast-       Language.HERMIT.Primitive.Navigation-       Language.HERMIT.Primitive.Navigation.Crumbs-       Language.HERMIT.Primitive.New-       Language.HERMIT.Primitive.Unfold+       HERMIT.External+       HERMIT.GHC+       HERMIT.Interp+       HERMIT.Kernel+       HERMIT.Kernel.Scoped+       HERMIT.Kure+       HERMIT.Kure.SumTypes+       HERMIT.Monad+       HERMIT.Optimize+       HERMIT.Parser+       HERMIT.ParserCore+       HERMIT.Plugin -       Language.HERMIT.PrettyPrinter.AST-       Language.HERMIT.PrettyPrinter.Clean-       Language.HERMIT.PrettyPrinter.Common-       Language.HERMIT.PrettyPrinter.GHC+       HERMIT.PrettyPrinter.AST+       HERMIT.PrettyPrinter.Clean+       HERMIT.PrettyPrinter.Common+       HERMIT.PrettyPrinter.GHC -       Language.HERMIT.Shell.Command+       HERMIT.Shell.Command+       HERMIT.Shell.Dictionary+       HERMIT.Shell.Externals+       HERMIT.Shell.ScriptToRewrite+       HERMIT.Shell.Renderer+       HERMIT.Shell.Types    Other-modules:-       Language.HERMIT.Syntax+       HERMIT.Syntax+       HERMIT.Utilities         Paths_hermit 
src/HERMIT.hs view
@@ -1,8 +1,7 @@ module HERMIT (plugin) where -import GhcPlugins--import Language.HERMIT.Optimize+import HERMIT.GHC+import HERMIT.Optimize  plugin :: Plugin plugin = optimize $ \ options -> phase 0 $ interactive [] options
+ src/HERMIT/Context.hs view
@@ -0,0 +1,287 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, InstanceSigs #-}++module HERMIT.Context+       ( -- * HERMIT Contexts+         -- ** Path Synonyms+         AbsolutePathH+       , LocalPathH+         -- ** The Standard Context+       , HermitC+       , initHermitC+         -- ** Bindings+       , HermitBindingSite(..)+       , BindingDepth+       , HermitBinding+       , hermitBindingSiteExpr+       , hermitBindingExpr+         -- ** Adding bindings to contexts+       , AddBindings(..)+       , addBindingGroup+       , addDefBinding+       , addDefBindingsExcept+       , addLambdaBinding+       , addAltBindings+       , addCaseWildBinding+       , addForallBinding+         -- ** Reading bindings from the context+       , BoundVars(..)+       , boundIn+       , findBoundVars+       , ReadBindings(..)+       , lookupHermitBinding+       , lookupHermitBindingDepth+       , lookupHermitBindingSite+         -- ** Accessing the Global Reader Environment from the context+       , HasGlobalRdrEnv(..)+         -- ** Accessing GHC rewrite rules from the context+       , HasCoreRules(..)+) where++import Prelude hiding (lookup)++import Control.Monad (liftM)++import Data.Monoid (mempty)+import Data.Map hiding (map, foldr, filter)++import qualified Language.Haskell.TH as TH++import Language.KURE+import Language.KURE.ExtendableContext++import HERMIT.Core+import HERMIT.GHC hiding (empty)++------------------------------------------------------------------------++-- | The depth of a binding.  Used, for example, to detect shadowing when inlining.+type BindingDepth = Int+++-- | HERMIT\'s representation of variable bindings.+--   Bound expressions cannot be inlined without checking for shadowing issues (using the depth information).+data HermitBindingSite = LAM                               -- ^ A lambda-bound variable.+                       | NONREC CoreExpr                   -- ^ A non-recursive binding of an expression.+                       | REC CoreExpr                      -- ^ A (potentially) recursive binding of an expression.+                       | SELFREC                           -- ^ A (potentially) recursive binding of a superexpression of the current node.+                       | CASEALT                           -- ^ A variable bound in a case alternative.+                       | CASEWILD CoreExpr (AltCon,[Var])  -- ^ A case wildcard binder.  We store both the scrutinised expression, and the case alternative 'AltCon' and variables.+                       | FORALL                            -- ^ A universally quantified type variable.++type HermitBinding = (BindingDepth, HermitBindingSite)++-- | Retrieve the expression in a 'HermitBindingSite', if there is one.+hermitBindingSiteExpr :: HermitBindingSite -> KureM CoreExpr+hermitBindingSiteExpr b = case b of+                            LAM          -> fail "variable is lambda-bound, not bound to an expression."+                            NONREC e     -> return e+                            REC e        -> return e+                            SELFREC      -> fail "identifier recursively refers to the expression under consideration."+                            CASEALT      -> fail "variable is bound in a case alternative, not bound to an expression."+                            CASEWILD e _ -> return e+                            FORALL       -> fail "variable is a universally quantified type variable."++-- | Retrieve the expression in a 'HermitBinding', if there is one.+hermitBindingExpr :: HermitBinding -> KureM CoreExpr+hermitBindingExpr = hermitBindingSiteExpr . snd++------------------------------------------------------------------------++-- | A class of contexts that can have HERMIT bindings added to them.+class AddBindings c where+  -- | Add a complete set of parrallel bindings to the context.+  --   (Parallel bindings occur in recursive let bindings and case alternatives.)+  --   This can also be used for solitary bindings (e.g. lambdas).+  --   Bindings are added in parallel sets to help with shadowing issues.+  addHermitBindings :: [(Var,HermitBindingSite)] -> c -> c++-- | The bindings are just discarded.+instance AddBindings (SnocPath crumb) where+  addHermitBindings :: [(Var,HermitBindingSite)] -> SnocPath crumb -> SnocPath crumb+  addHermitBindings _ = id++-- | The bindings are added to the base context and the extra context.+instance (AddBindings c, AddBindings e) => AddBindings (ExtendContext c e) where+  addHermitBindings :: [(Var,HermitBindingSite)] -> ExtendContext c e -> ExtendContext c e+  addHermitBindings bnds c = c+                              { baseContext  = addHermitBindings bnds (baseContext c)+                              , extraContext = addHermitBindings bnds (extraContext c)+                              }++-------------------------------------------++-- | Add a single binding to the context.+addHermitBinding  :: AddBindings c => Var -> HermitBindingSite -> c -> c+addHermitBinding v bd = addHermitBindings [(v,bd)]++-- | Add all bindings in a binding group to a context.+addBindingGroup :: AddBindings c => CoreBind -> c -> c+addBindingGroup (NonRec v e) = addHermitBinding  v (NONREC e)+addBindingGroup (Rec ies)    = addHermitBindings [ (i, REC e) | (i,e) <- ies ]++-- | Add the binding for a recursive definition currently under examination.+--   Note that because the expression may later be modified, the context only records the identifier, not the expression.+addDefBinding :: AddBindings c => Id -> c -> c+addDefBinding i = addHermitBinding i SELFREC++-- | Add a list of recursive bindings to the context, except the nth binding in the list.+--   The idea is to exclude the definition being descended into.+addDefBindingsExcept :: AddBindings c => Int -> [(Id,CoreExpr)] -> c -> c+addDefBindingsExcept n ies = addHermitBindings [ (i, REC e) | (m,(i,e)) <- zip [0..] ies, m /= n ]++-- | Add a wildcard binding for a specific case alternative.+addCaseWildBinding :: AddBindings c => (Id,CoreExpr,CoreAlt) -> c -> c+addCaseWildBinding (i,e,(con,vs,_)) = addHermitBinding i (CASEWILD e (con,vs))++-- | Add a lambda bound variable to a context.+--   All that is known is the variable, which may shadow something.+--   If so, we don't worry about that here, it is instead checked during inlining.+addLambdaBinding :: AddBindings c => Var -> c -> c+addLambdaBinding v = addHermitBinding v LAM++-- | Add the variables bound by a 'DataCon' in a case.+--   They are all bound at the same depth.+addAltBindings :: AddBindings c => [Var] -> c -> c+addAltBindings vs = addHermitBindings [ (v, CASEALT) | v <- vs ]++-- | Add a universally quantified type variable to a context.+addForallBinding :: AddBindings c => TyVar -> c -> c+addForallBinding v = addHermitBinding v FORALL++------------------------------------------------------------------------++-- | A class of contexts that stores the set of variables in scope that have been bound during the traversal.+class BoundVars c where+  boundVars :: c -> VarSet++instance BoundVars VarSet where+  boundVars :: VarSet -> VarSet+  boundVars = id++-- | List all variables bound in the context that match the given name.+findBoundVars :: BoundVars c => TH.Name -> c -> VarSet+findBoundVars nm = filterVarSet (cmpTHName2Var nm) . boundVars+++-- | A class of contexts from which HERMIT bindings can be retrieved.+class BoundVars c => ReadBindings c where+  hermitDepth    :: c -> BindingDepth+  hermitBindings :: c -> Map Var HermitBinding++-- | Determine if a variable is bound in a context.+boundIn :: ReadBindings c => Var -> c -> Bool+boundIn i c = i `member` hermitBindings c++-- | Lookup the binding for a variable in a context.+lookupHermitBinding :: (ReadBindings c, Monad m) => Var -> c -> m HermitBinding+lookupHermitBinding v = maybe (fail "binding not found in HERMIT context.") return . lookup v . hermitBindings++-- | Lookup the depth of a variable's binding in a context.+lookupHermitBindingDepth :: (ReadBindings c, Monad m) => Var -> c -> m BindingDepth+lookupHermitBindingDepth v = liftM fst . lookupHermitBinding v++-- | Lookup the binding for a variable in a context, ensuring it was bound at the specified depth.+lookupHermitBindingSite :: (ReadBindings c, Monad m) => Var -> BindingDepth -> c -> m HermitBindingSite+lookupHermitBindingSite v depth c = do (d,bnd) <- lookupHermitBinding v c+                                       guardMsg (d == depth) "lookupHermitBinding succeeded, but depth does not match.  The variable has probably been shadowed."+                                       return bnd++------------------------------------------------------------------------++-- | A class of contexts that store GHC rewrite rules.+class HasCoreRules c where+  hermitCoreRules :: c -> [CoreRule]++instance HasCoreRules [CoreRule] where+  hermitCoreRules :: [CoreRule] -> [CoreRule]+  hermitCoreRules = id++------------------------------------------------------------------------++-- | A class of contexts that store the Global Reader Environment.+class HasGlobalRdrEnv c where+  hermitGlobalRdrEnv :: c -> GlobalRdrEnv++instance HasGlobalRdrEnv GlobalRdrEnv where+  hermitGlobalRdrEnv :: GlobalRdrEnv -> GlobalRdrEnv+  hermitGlobalRdrEnv = id++------------------------------------------------------------------------++type AbsolutePathH = AbsolutePath Crumb+type LocalPathH = LocalPath Crumb++-- | The HERMIT context, containing all bindings in scope and the current location in the AST.+--   The bindings here are lazy by choice, so that we can avoid the cost+--   of building the context if we never use it.+data HermitC = HermitC+        { hermitC_bindings       :: Map Var HermitBinding   -- ^ All (important) bindings in scope.+        , hermitC_depth          :: BindingDepth            -- ^ The depth of the most recent bindings.+        , hermitC_path           :: AbsolutePathH           -- ^ The 'AbsolutePath' to the current node from the root.+        , hermitC_globalRdrEnv   :: GlobalRdrEnv            -- ^ The top-level lexical environment.+        , hermitC_coreRules      :: [CoreRule]              -- ^ GHC rewrite RULES.+        }++------------------------------------------------------------------------++-- | Create the initial HERMIT 'HermitC' by providing a 'ModGuts'.+initHermitC :: ModGuts -> HermitC+initHermitC modGuts = HermitC+                        { hermitC_bindings      = empty+                        , hermitC_depth         = 0+                        , hermitC_path          = mempty+                        , hermitC_globalRdrEnv  = mg_rdr_env modGuts+                        , hermitC_coreRules     = mg_rules modGuts ++ other_rules+                        }++    where other_rules :: [CoreRule]+          other_rules = mg_binds modGuts >>= bindToVarExprs >>= (idCoreRules . fst)++------------------------------------------------------------------------++-- | Retrieve the 'AbsolutePath' to the current node, from the HERMIT context.+instance ReadPath HermitC Crumb where+  absPath :: HermitC -> AbsolutePath Crumb+  absPath = hermitC_path++-- | Extend the 'AbsolutePath' stored in the HERMIT context.+instance ExtendPath HermitC Crumb where+  (@@) :: HermitC -> Crumb -> HermitC+  c @@ n = c { hermitC_path = hermitC_path c @@ n }++------------------------------------------------------------------------++instance AddBindings HermitC where+  addHermitBindings :: [(Var,HermitBindingSite)] -> HermitC -> HermitC+  addHermitBindings vbs c = let nextDepth = succ (hermitC_depth c)+                                vhbs      = [ (v, (nextDepth,b)) | (v,b) <- vbs ]+                             in c { hermitC_bindings = fromList vhbs `union` hermitC_bindings c+                                  , hermitC_depth    = nextDepth+                                  }++------------------------------------------------------------------------++instance BoundVars HermitC where+  boundVars :: HermitC -> VarSet+  boundVars =  mkVarSet . keys . hermitC_bindings++instance ReadBindings HermitC where+  hermitDepth :: HermitC -> BindingDepth+  hermitDepth = hermitC_depth++  hermitBindings :: HermitC -> Map Var HermitBinding+  hermitBindings = hermitC_bindings++------------------------------------------------------------------------++instance HasCoreRules HermitC where+  hermitCoreRules :: HermitC -> [CoreRule]+  hermitCoreRules = hermitC_coreRules++------------------------------------------------------------------------++instance HasGlobalRdrEnv HermitC where+  hermitGlobalRdrEnv :: HermitC -> GlobalRdrEnv+  hermitGlobalRdrEnv = hermitC_globalRdrEnv++------------------------------------------------------------------------
+ src/HERMIT/Core.hs view
@@ -0,0 +1,549 @@+{-# LANGUAGE CPP, LambdaCase #-}+module HERMIT.Core+          (+          -- * Generic Data Type+            CoreProg(..)+          , CoreDef(..)+          , CoreTickish+          -- * Equality+          -- | We define both syntactic equality and alpha equality.++          -- ** Syntactic Equality+          , progSyntaxEq+          , bindSyntaxEq+          , defSyntaxEq+          , exprSyntaxEq+          , altSyntaxEq+          , typeSyntaxEq+          , coercionSyntaxEq++          -- ** Alpha Equality+          , progAlphaEq+          , bindAlphaEq+          , defAlphaEq+          , exprAlphaEq+          , altAlphaEq+          , typeAlphaEq+          , coercionAlphaEq++          -- * Conversions to/from 'Core'+          , defsToRecBind+          , defToIdExpr+          , progToBinds+          , bindsToProg+          , bindToVarExprs++          -- * Collecting variable bindings+          , progIds+          , bindVars+          , defId+          , altVars++          -- * Collecting free variables+          -- $freeVarsNote+          , freeVarsProg+          , freeVarsBind+          , freeVarsDef+          , freeVarsExpr+          , freeVarsAlt+          , freeVarsType+          , freeVarsCoercion+          , localFreeVarsExpr+          , freeIdsExpr+          , localFreeIdsExpr++          -- * Utilities+          , isCoArg+          , exprKindOrType+          , exprTypeM+          , endoFunType+          , splitFunTypeM+          , funArgResTypes+          , funsWithInverseTypes+          , appCount+          , mapAlts++          -- * Crumbs+          , Crumb(..)+          , showCrumbs+--          , crumbToDeprecatedInt+          , deprecatedLeftSibling+          , deprecatedRightSibling+) where++import Control.Monad ((>=>))++import Language.KURE.Combinators.Monad+import Language.KURE.MonadCatch++import HERMIT.GHC++import Data.List (intercalate)++-----------------------------------------------------------------------++-- | Unlike everything else, there is no synonym for 'Tickish' 'Id' provided by GHC, so we define one.+type CoreTickish = Tickish Id++---------------------------------------------------------------------++-- | A program is a telescope of nested binding groups.+--   That is, each binding scopes over the remainder of the program.+--   In GHC Core, programs are encoded as ['CoreBind'].+--   This data type is isomorphic.+data CoreProg = ProgNil                     -- ^ An empty program.+              | ProgCons CoreBind CoreProg  -- ^ A binding group and the program it scopes over.++infixr 5 `ProgCons`++-- | Get the list of bindings in a program.+progToBinds :: CoreProg -> [CoreBind]+progToBinds ProgNil         = []+progToBinds (ProgCons bd p) = bd : progToBinds p+-- recursive, don't inline++-- | Build a program from a list of bindings.+--   Note that bindings earlier in the list are considered scope over bindings later in the list.+bindsToProg :: [CoreBind] -> CoreProg+bindsToProg = foldr ProgCons ProgNil+{-# INLINE bindsToProg #-}++-- | Extract the list of identifier/expression pairs from a binding group.+bindToVarExprs :: CoreBind -> [(Var,CoreExpr)]+bindToVarExprs (NonRec v e) = [(v,e)]+bindToVarExprs (Rec bds)    = bds+{-# INLINE bindToVarExprs #-}++-- | A (potentially recursive) definition is an identifier and an expression.+--   In GHC Core, recursive definitions are encoded as ('Id', 'CoreExpr') pairs.+--   This data type is isomorphic.+data CoreDef = Def Id CoreExpr++-- | Convert a definition to an identifier/expression pair.+defToIdExpr :: CoreDef -> (Id,CoreExpr)+defToIdExpr (Def v e) = (v,e)+{-# INLINE defToIdExpr #-}++-- | Convert a list of recursive definitions into an (isomorphic) recursive binding group.+defsToRecBind :: [CoreDef] -> CoreBind+defsToRecBind = Rec . map defToIdExpr+{-# INLINE defsToRecBind #-}++-----------------------------------------------------------------------++-- Syntactic Equality++-- | Syntactic Equality of programs.+progSyntaxEq :: CoreProg -> CoreProg -> Bool+progSyntaxEq ProgNil ProgNil                       = True+progSyntaxEq (ProgCons bnd1 p1) (ProgCons bnd2 p2) = bindSyntaxEq bnd1 bnd2 && progSyntaxEq p1 p2+progSyntaxEq _ _                                   = False++-- | Syntactic Equality of binding groups.+bindSyntaxEq :: CoreBind -> CoreBind -> Bool+bindSyntaxEq (NonRec v1 e1) (NonRec v2 e2) = v1 == v2 && exprSyntaxEq e1 e2+bindSyntaxEq (Rec ies1)     (Rec ies2)     = all2 (\ (i1,e1) (i2,e2) -> i1 == i2 && exprSyntaxEq e1 e2) ies1 ies2+bindSyntaxEq _              _              = False++-- | Syntactic Equality of recursive definitions.+defSyntaxEq :: CoreDef -> CoreDef -> Bool+defSyntaxEq (Def i1 e1) (Def i2 e2) = i1 == i2 && exprSyntaxEq e1 e2++-- | Syntactic Equality of expressions.+exprSyntaxEq :: CoreExpr -> CoreExpr -> Bool+exprSyntaxEq (Var i1)             (Var i2)             = i1 == i2+exprSyntaxEq (Lit l1)             (Lit l2)             = l1 == l2+exprSyntaxEq (App f1 e1)          (App f2 e2)          = exprSyntaxEq f1 f2 && exprSyntaxEq e1 e2+exprSyntaxEq (Lam v1 e1)          (Lam v2 e2)          = v1 == v2 && exprSyntaxEq e1 e2+exprSyntaxEq (Let b1 e1)          (Let b2 e2)          = bindSyntaxEq b1 b2 && exprSyntaxEq e1 e2+exprSyntaxEq (Case s1 w1 ty1 as1) (Case s2 w2 ty2 as2) = w1 == w2 && exprSyntaxEq s1 s2 && all2 altSyntaxEq as1 as2 && typeSyntaxEq ty1 ty2+exprSyntaxEq (Cast e1 co1)        (Cast e2 co2)        = exprSyntaxEq e1 e2 && coercionSyntaxEq co1 co2+exprSyntaxEq (Tick t1 e1)         (Tick t2 e2)         = t1 == t2 && exprSyntaxEq e1 e2+exprSyntaxEq (Type ty1)           (Type ty2)           = typeSyntaxEq ty1 ty2+exprSyntaxEq (Coercion co1)       (Coercion co2)       = coercionSyntaxEq co1 co2+exprSyntaxEq _                    _                    = False++-- | Syntactic Equality of case alternatives.+altSyntaxEq :: CoreAlt -> CoreAlt -> Bool+altSyntaxEq (c1,vs1,e1) (c2,vs2,e2) = c1 == c2 && vs1 == vs2 && exprSyntaxEq e1 e2++-- | Syntactic Equality of 'Type's.+typeSyntaxEq :: Type -> Type -> Bool+typeSyntaxEq (TyVarTy v1)      (TyVarTy v2)         = v1 == v2+typeSyntaxEq (LitTy l1)        (LitTy l2)           = l1 == l2+typeSyntaxEq (AppTy t1 ty1)    (AppTy t2 ty2)       = typeSyntaxEq t1 t2 && typeSyntaxEq ty1 ty2+typeSyntaxEq (FunTy t1 ty1)    (FunTy t2 ty2)       = typeSyntaxEq t1 t2 && typeSyntaxEq ty1 ty2+typeSyntaxEq (ForAllTy v1 ty1) (ForAllTy v2 ty2)    = v1 == v2 && typeSyntaxEq ty1 ty2+typeSyntaxEq (TyConApp c1 ts1) (TyConApp c2 ts2)    = c1 == c2 && all2 typeSyntaxEq ts1 ts2+typeSyntaxEq _                 _                    = False++-- | Syntactic Equality of 'Coercion's.+coercionSyntaxEq :: Coercion -> Coercion -> Bool+#if __GLASGOW_HASKELL__ > 706+coercionSyntaxEq (Refl role1 ty1)        (Refl role2 ty2)        = role1 == role2 && typeSyntaxEq ty1 ty2+coercionSyntaxEq (TyConAppCo role1 tc1 cos1) (TyConAppCo role2 tc2 cos2) = role1 == role2 && tc1 == tc2 && all2 coercionSyntaxEq cos1 cos2+#else+coercionSyntaxEq (Refl ty1)              (Refl ty2)              = typeSyntaxEq ty1 ty2+coercionSyntaxEq (TyConAppCo tc1 cos1)   (TyConAppCo tc2 cos2)   = tc1 == tc2 && all2 coercionSyntaxEq cos1 cos2+#endif+coercionSyntaxEq (AppCo co11 co12)       (AppCo co21 co22)       = coercionSyntaxEq co11 co21 && coercionSyntaxEq co12 co22+coercionSyntaxEq (ForAllCo v1 co1)       (ForAllCo v2 co2)       = v1 == v2 && coercionSyntaxEq co1 co2+coercionSyntaxEq (CoVarCo v1)            (CoVarCo v2)            = v1 == v2+#if __GLASGOW_HASKELL__ > 706+coercionSyntaxEq (AxiomInstCo con1 ind1 cos1) (AxiomInstCo con2 ind2 cos2) = con1 == con2 && ind1 == ind2 && all2 coercionSyntaxEq cos1 cos2+coercionSyntaxEq (LRCo lr1 co1)          (LRCo lr2 co2)          = lr1 == lr2 && coercionSyntaxEq co1 co2+coercionSyntaxEq (UnivCo role1 ty11 ty12) (UnivCo role2 ty21 ty22) = role1 == role2 && typeSyntaxEq ty11 ty21 && typeSyntaxEq ty12 ty22+#else+coercionSyntaxEq (AxiomInstCo con1 cos1) (AxiomInstCo con2 cos2) = con1 == con2 && all2 coercionSyntaxEq cos1 cos2+coercionSyntaxEq (UnsafeCo ty11 ty12)    (UnsafeCo ty21 ty22)    = typeSyntaxEq ty11 ty21 && typeSyntaxEq ty12 ty22+#endif+coercionSyntaxEq (SymCo co1)             (SymCo co2)             = coercionSyntaxEq co1 co2+coercionSyntaxEq (TransCo co11 co12)     (TransCo co21 co22)     = coercionSyntaxEq co11 co21 && coercionSyntaxEq co12 co22+coercionSyntaxEq (NthCo n1 co1)          (NthCo n2 co2)          = n1 == n2 && coercionSyntaxEq co1 co2+coercionSyntaxEq (InstCo co1 ty1)        (InstCo co2 ty2)        = coercionSyntaxEq co1 co2 && typeSyntaxEq ty1 ty2+coercionSyntaxEq _                       _                       = False++-----------------------------------------------------------------------++-- Alpha Equality++-- | Alpha equality of programs.+progAlphaEq :: CoreProg -> CoreProg -> Bool+progAlphaEq ProgNil ProgNil                       = True+progAlphaEq (ProgCons bnd1 p1) (ProgCons bnd2 p2) = bindVars bnd1 == bindVars bnd2 && bindAlphaEq bnd1 bnd2 && progAlphaEq p1 p2+progAlphaEq _ _                                   = False++-- The ideas for this function are directly extracted from+-- the GHC function, CoreUtils.eqExprX+-- | Alpha equality of binding groups.+bindAlphaEq :: CoreBind -> CoreBind -> Bool+bindAlphaEq (NonRec _ e1) (NonRec _ e2) = exprAlphaEq e1 e2+bindAlphaEq (Rec ps1)     (Rec ps2)     = all2 (eqExprX id_unf env) rs1 rs2+  where+    id_unf _   = noUnfolding      -- Don't expand+    (bs1,rs1)  = unzip ps1+    (bs2,rs2)  = unzip ps2+    inScopeSet = mkInScopeSet $ exprsFreeVars (rs1 ++ rs2)+    env        = rnBndrs2 (mkRnEnv2 inScopeSet) bs1 bs2+bindAlphaEq _ _ = False++-- | Alpha equality of recursive definitions.+defAlphaEq :: CoreDef -> CoreDef -> Bool+defAlphaEq d1 d2 = defsToRecBind [d1] `bindAlphaEq` defsToRecBind [d2]++-- | Alpha equality of expressions.+exprAlphaEq :: CoreExpr -> CoreExpr -> Bool+exprAlphaEq e1 e2 = eqExpr (mkInScopeSet $ exprsFreeVars [e1, e2]) e1 e2++-- The ideas for this function are directly extracted from+-- the GHC function, CoreUtils.eqExprX+-- | Alpha equality of case alternatives.+altAlphaEq :: CoreAlt -> CoreAlt -> Bool+altAlphaEq (c1,vs1,e1) (c2,vs2,e2) = c1 == c2 && eqExprX id_unf env e1 e2+  where+    id_unf _    = noUnfolding      -- Don't expand+    inScopeSet  = mkInScopeSet $ exprsFreeVars [e1,e2]+    env         = rnBndrs2 (mkRnEnv2 inScopeSet) vs1 vs2++-- | Alpha equality of types.+typeAlphaEq :: Type -> Type -> Bool+typeAlphaEq = eqType++-- | Alpha equality of coercions.+coercionAlphaEq :: Coercion -> Coercion -> Bool+coercionAlphaEq = coreEqCoercion++-----------------------------------------------------------------------++-- | List all identifiers bound at the top-level in a program.+progIds :: CoreProg -> [Id]+progIds = \case+             ProgNil        -> []+             ProgCons bnd p -> bindVars bnd ++ progIds p++-- | List all variables bound in a binding group.+bindVars :: CoreBind -> [Var]+bindVars = \case+              NonRec v _ -> [v]+              Rec ds     -> map fst ds++-- | Return the identifier bound by a recursive definition.+defId :: CoreDef -> Id+defId (Def i _) = i++-- | List the variables bound by a case alternative.+altVars :: CoreAlt -> [Var]+altVars (_,vs,_) = vs++-----------------------------------------------------------------------++-- $freeVarsNote+-- The GHC Function exprFreeVars defined in "CoreFVs" only returns *locally-defined* free variables.+-- In HERMIT, this is typically not what we want, so we define our own functions.+-- We reuse some of the functionality in "CoreFVs", but alas much of it is not exposed, so we have to reimplement some of it.++-- | Find all free variables in an expression.+freeVarsExpr :: CoreExpr -> VarSet+freeVarsExpr = exprSomeFreeVars (const True)++-- | Find all free identifiers in an expression.+freeIdsExpr :: CoreExpr -> IdSet+freeIdsExpr = exprSomeFreeVars isId++-- | Find all locally defined free variables in an expression.+localFreeVarsExpr :: CoreExpr -> VarSet+localFreeVarsExpr = exprSomeFreeVars isLocalVar++-- | Find all locally defined free identifiers in an expression.+localFreeIdsExpr :: CoreExpr -> VarSet+localFreeIdsExpr = exprSomeFreeVars isLocalId+++-- | Find all free identifiers in a binding group, which excludes any variables bound in the group.+freeVarsBind :: CoreBind -> VarSet+freeVarsBind (NonRec v e) = freeVarsExpr e `unionVarSet` varTypeTyVars v+freeVarsBind (Rec defs)   = let (bs,es) = unzip defs+                             in delVarSetList (unionVarSets $ map freeVarsExpr es) bs+                                `unionVarSet`  unionVarSets (map varTypeTyVars bs)++-- | Find all free variables is a recursive definition, which excludes the bound variable.+freeVarsDef :: CoreDef -> VarSet+freeVarsDef (Def v e) = delVarSet (freeVarsExpr e) v `unionVarSet` varTypeTyVars v++-- | Find all free variables in a case alternative, which excludes any variables bound in the alternative.+freeVarsAlt :: CoreAlt -> VarSet+freeVarsAlt (_,bs,e) = delVarSetList (freeVarsExpr e `unionVarSet` unionVarSets (map varTypeTyVars bs)) bs++-- | Find all free variables in a program.+freeVarsProg :: CoreProg -> VarSet+freeVarsProg = \case+                  ProgNil        -> emptyVarSet+                  ProgCons bnd p -> freeVarsBind bnd `unionVarSet` delVarSetList (freeVarsProg p) (bindVars bnd)++-- | Find all free variables in a type.+freeVarsType :: Type -> TyVarSet+freeVarsType = tyVarsOfType++-- | Find all free variables in a coercion.+freeVarsCoercion :: Coercion -> VarSet+freeVarsCoercion = tyCoVarsOfCo++-----------------------------------------------------------------------++-- | GHC's 'exprType' function throws an error if applied to a 'Type'.+--   This function returns the 'Kind' of a 'Type', but otherwise behaves as 'exprType'.+exprKindOrType :: CoreExpr -> KindOrType+exprKindOrType (Type t)  = typeKind t+exprKindOrType e         = exprType e++-- | GHC's 'exprType' function throws an error if applied to a 'Type'.+--   This function catches that case as failure in an arbitrary monad.+exprTypeM :: Monad m => CoreExpr -> m Type+exprTypeM (Type _) = fail "exprTypeM failed: expression is a type, so does not have a type."+exprTypeM e        = return (exprType e)++-- | Returns @True@ iff the expression is a 'Coercion' expression at its top level.+isCoArg :: CoreExpr -> Bool+isCoArg (Coercion {}) = True+isCoArg _             = False++-----------------------------------------------------------------------++-- | Count the number of nested applications.+appCount :: CoreExpr -> Int+appCount (App e1 _) = appCount e1 + 1+appCount _          = 0+-- don't inline, recursive++-----------------------------------------------------------------------++-- | Map a function over the RHS of each case alternative.+mapAlts :: (CoreExpr -> CoreExpr) -> [CoreAlt] -> [CoreAlt]+mapAlts f alts = [ (ac, vs, f e) | (ac, vs, e) <- alts ]++-----------------------------------------------------------------------++-- | Return the domain/codomain type of an endofunction expression.+endoFunType :: Monad m => CoreExpr -> m Type+endoFunType f = do (ty1,ty2) <- funArgResTypes f+                   guardMsg (eqType ty1 ty2) ("argument and result types differ.")+                   return ty1++-- | Return the domain and codomain types of a function type, if it is a function type.+splitFunTypeM :: Monad m => Type -> m (Type,Type)+splitFunTypeM = maybe (fail "not a function type.") return . splitFunTy_maybe++-- | Return the domain and codomain types of a function expression.+funArgResTypes :: Monad m => CoreExpr -> m (Type,Type)+funArgResTypes = exprTypeM >=> splitFunTypeM++-- | Check two expressions have types @a -> b@ and @b -> a@, returning @(a,b)@.+funsWithInverseTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type,Type)+funsWithInverseTypes f g = do (fdom,fcod) <- funArgResTypes f+                              (gdom,gcod) <- funArgResTypes g+                              setFailMsg "functions do not have inverse types." $+                                do guardM (eqType fdom gcod)+                                   guardM (eqType gdom fcod)+                                   return (fdom,fcod)++-----------------------------------------------------------------------++-- | Crumbs record a path through the tree, using descriptive constructor names.+data Crumb =+           -- ModGuts+             ModGuts_Prog+           -- Prog+           | ProgCons_Head | ProgCons_Tail+           -- Bind+           | NonRec_RHS | NonRec_Var+           | Rec_Def Int+           -- Def+           | Def_Id | Def_RHS+           -- Expr+           | Var_Id+           | Lit_Lit+           | App_Fun | App_Arg+           | Lam_Var | Lam_Body+           | Let_Bind | Let_Body+           | Case_Scrutinee | Case_Binder | Case_Type | Case_Alt Int+           | Cast_Expr | Cast_Co+           | Tick_Tick | Tick_Expr+           | Type_Type+           | Co_Co+           -- Alt+           | Alt_Con | Alt_Var Int | Alt_RHS+           -- Type+           | TyVarTy_TyVar+           | LitTy_TyLit+           | AppTy_Fun | AppTy_Arg+           | TyConApp_TyCon | TyConApp_Arg Int+           | FunTy_Dom | FunTy_CoDom+           | ForAllTy_Var | ForAllTy_Body+           -- Coercion+           | Refl_Type+           | TyConAppCo_TyCon | TyConAppCo_Arg Int+           | AppCo_Fun | AppCo_Arg+           | ForAllCo_TyVar | ForAllCo_Body+           | CoVarCo_CoVar+           | AxiomInstCo_Axiom | AxiomInstCo_Index | AxiomInstCo_Arg Int+           | UnsafeCo_Left | UnsafeCo_Right+           | SymCo_Co+           | TransCo_Left | TransCo_Right+           | NthCo_Int | NthCo_Co+           | InstCo_Co | InstCo_Type+           | LRCo_LR | LRCo_Co+           deriving (Eq,Read,Show)+           -- TODO: Write a prettier Show instance+++showCrumbs :: [Crumb] -> String+showCrumbs crs = "[" ++ intercalate ", " (map showCrumb crs) ++ "]"++-- Note, these should match the external names in HERMIT.Primitive.Navigation.Crumbs+showCrumb :: Crumb -> String+showCrumb = \case+               ModGuts_Prog   -> "prog"+               ProgCons_Head  -> "prog-head"+               ProgCons_Tail  -> "prog-tail"+               NonRec_RHS     -> "nonrec-rhs"+               Rec_Def n      -> "rec-def " ++ show n+               Def_RHS        -> "def-rhs"+               App_Fun        -> "app-fun"+               App_Arg        -> "app-arg"+               Lam_Body       -> "lam-body"+               Let_Bind       -> "let-bind"+               Let_Body       -> "let-body"+               Case_Scrutinee -> "case-expr"+               Case_Type      -> "case-type"+               Case_Alt n     -> "case-alt " ++ show n+               Cast_Expr      -> "cast-expr"+               Cast_Co        -> "cast-co"+               Tick_Expr      -> "tick-expr"+               Alt_RHS        -> "alt-rhs"+               Type_Type      -> "type"+               Co_Co          -> "coercion"+               -- Types+               AppTy_Fun      -> "appTy-fun"+               AppTy_Arg      -> "appTy-arg"+               TyConApp_Arg n -> "tyCon-arg " ++ show n+               FunTy_Dom      -> "fun-dom"+               FunTy_CoDom    -> "fun-cod"+               ForAllTy_Body  -> "forall-body"+               -- Coercions+               Refl_Type         -> "refl-type"+               TyConAppCo_Arg n  -> "coCon-arg " ++ show n+               AppCo_Fun         -> "appCo-fun"+               AppCo_Arg         -> "appCo-arg"+               ForAllCo_Body     -> "coForall-body"+               AxiomInstCo_Arg n -> "axiom-inst " ++ show n+               UnsafeCo_Left     -> "unsafe-left"+               UnsafeCo_Right    -> "unsafe-right"+               SymCo_Co          -> "sym-co"+               TransCo_Left      -> "trans-left"+               TransCo_Right     -> "trans-right"+               NthCo_Co          -> "nth-co"+               InstCo_Co         -> "inst-co"+               InstCo_Type       -> "inst-type"+               LRCo_Co           -> "lr-co"++               _              -> "Warning: Crumb should not be in use!  This is probably Neil's fault."++{-+-- | Earlier versions of HERMIT used 'Int' as the crumb type.+--   This function maps a 'Crumb' back to that corresponding 'Int', for backwards compatibility purposes.+crumbToDeprecatedInt :: Crumb -> Maybe Int+crumbToDeprecatedInt = \case+                          ModGuts_Prog   -> Just 0+                          ProgCons_Bind  -> Just 0+                          ProgCons_Tail  -> Just 1+                          NonRec_RHS     -> Just 0+                          NonRec_Var     -> Nothing+                          Rec_Def n      -> Just n+                          Def_Id         -> Nothing+                          Def_RHS        -> Just 0+                          App_Fun        -> Just 0+                          App_Arg        -> Just 1+                          Lam_Var        -> Nothing+                          Lam_Body       -> Just 0+                          Let_Bind       -> Just 0+                          Let_Body       -> Just 1+                          Case_Scrutinee -> Just 0+                          Case_Binder    -> Nothing+                          Case_Type      -> Nothing+                          Case_Alt n     -> Just (n + 1)+                          Cast_Expr      -> Just 0+                          Cast_Co        -> Nothing+                          Tick_Tick      -> Nothing+                          Tick_Expr      -> Just 0+                          Type_Type      -> Nothing+                          Co_Co          -> Nothing+                          Alt_Con        -> Nothing+                          Alt_Var _      -> Nothing+                          Alt_RHS        -> Just 0+-}+-- | Converts a 'Crumb' into the 'Crumb' pointing to its left-sibling, if a such a 'Crumb' exists.+--   This is for backwards compatibility purposes with the old Int representation.+deprecatedLeftSibling :: Crumb -> Maybe Crumb+deprecatedLeftSibling = \case+                           ProgCons_Tail       -> Just ProgCons_Head+                           Rec_Def n | n > 0   -> Just (Rec_Def (n-1))+                           App_Arg             -> Just App_Fun+                           Let_Body            -> Just Let_Bind+                           Case_Alt n | n == 0 -> Just Case_Scrutinee+                                      | n >  0 -> Just (Case_Alt (n-1))+                           _                   -> Nothing++-- | Converts a 'Crumb' into the 'Crumb' pointing to its right-sibling, if a such a 'Crumb' exists.+--   This is for backwards compatibility purposes with the old Int representation.+deprecatedRightSibling :: Crumb -> Maybe Crumb+deprecatedRightSibling = \case+                           ProgCons_Head       -> Just ProgCons_Tail+                           Rec_Def n           -> Just (Rec_Def (n+1))+                           App_Fun             -> Just App_Arg+                           Let_Bind            -> Just Let_Body+                           Case_Scrutinee      -> Just (Case_Alt 0)+                           Case_Alt n          -> Just (Case_Alt (n+1))+                           _                   -> Nothing+++-----------------------------------------------------------------------
+ src/HERMIT/Dictionary.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE ScopedTypeVariables #-}++module HERMIT.Dictionary+    ( -- * The HERMIT Dictionary+      externals+    , module HERMIT.Dictionary.AlphaConversion+    , module HERMIT.Dictionary.Common+    , module HERMIT.Dictionary.Composite+    , module HERMIT.Dictionary.Debug+    , module HERMIT.Dictionary.FixPoint+    , module HERMIT.Dictionary.Fold+    , module HERMIT.Dictionary.Function+    , module HERMIT.Dictionary.GHC+    , module HERMIT.Dictionary.Inline+    , module HERMIT.Dictionary.Local+    , module HERMIT.Dictionary.Navigation+    , module HERMIT.Dictionary.New+    , module HERMIT.Dictionary.Query+    , module HERMIT.Dictionary.Reasoning+    , module HERMIT.Dictionary.Undefined+    , module HERMIT.Dictionary.Unfold+    , module HERMIT.Dictionary.Unsafe+    , module HERMIT.Dictionary.WorkerWrapper.Fix+    , module HERMIT.Dictionary.WorkerWrapper.FixResult+    ) where++import HERMIT.External++-- Since you cannot re-export qualified modules, we import everything *twice*.+import           HERMIT.Dictionary.AlphaConversion hiding (externals)+import qualified HERMIT.Dictionary.AlphaConversion as Alpha+import           HERMIT.Dictionary.Common -- TODO: deal with this module+import           HERMIT.Dictionary.Composite hiding (externals)+import qualified HERMIT.Dictionary.Composite as Composite+import           HERMIT.Dictionary.Debug hiding (externals)+import qualified HERMIT.Dictionary.Debug as Debug+import           HERMIT.Dictionary.FixPoint hiding (externals)+import qualified HERMIT.Dictionary.FixPoint as FixPoint+import           HERMIT.Dictionary.Fold hiding (externals)+import qualified HERMIT.Dictionary.Fold as Fold+import           HERMIT.Dictionary.Function hiding (externals)+import qualified HERMIT.Dictionary.Function as Function+import           HERMIT.Dictionary.GHC hiding (externals)+import qualified HERMIT.Dictionary.GHC as GHC+import           HERMIT.Dictionary.Inline hiding (externals)+import qualified HERMIT.Dictionary.Inline as Inline+import qualified HERMIT.Dictionary.Kure as Kure -- This *only* exports externals, so we don't re-export it.+import           HERMIT.Dictionary.Local hiding (externals)+import qualified HERMIT.Dictionary.Local as Local+import           HERMIT.Dictionary.Navigation hiding (externals)+import qualified HERMIT.Dictionary.Navigation as Navigation+import           HERMIT.Dictionary.New hiding (externals)+import qualified HERMIT.Dictionary.New as New+import           HERMIT.Dictionary.Query hiding (externals)+import qualified HERMIT.Dictionary.Query as Query+import           HERMIT.Dictionary.Reasoning hiding (externals)+import qualified HERMIT.Dictionary.Reasoning as Reasoning+import           HERMIT.Dictionary.Undefined hiding (externals)+import qualified HERMIT.Dictionary.Undefined as Undefined+import           HERMIT.Dictionary.Unfold hiding (externals)+import qualified HERMIT.Dictionary.Unfold as Unfold+import           HERMIT.Dictionary.Unsafe hiding (externals)+import qualified HERMIT.Dictionary.Unsafe as Unsafe+import           HERMIT.Dictionary.WorkerWrapper.Fix hiding (externals)+import qualified HERMIT.Dictionary.WorkerWrapper.Fix as WorkerWrapperFix+import           HERMIT.Dictionary.WorkerWrapper.FixResult hiding (externals)+import qualified HERMIT.Dictionary.WorkerWrapper.FixResult as WorkerWrapperFixResult++--------------------------------------------------------------------------++-- | List of all 'External's provided by HERMIT.+externals :: [External]+externals =+       Alpha.externals+    ++ Composite.externals+    ++ Debug.externals+    ++ FixPoint.externals+    ++ Fold.externals+    ++ Function.externals+    ++ GHC.externals+    ++ Inline.externals+    ++ Kure.externals+    ++ Local.externals+    ++ Navigation.externals+    ++ New.externals+    ++ Query.externals+    ++ Reasoning.externals+    ++ Undefined.externals+    ++ Unfold.externals+    ++ Unsafe.externals+    ++ WorkerWrapperFix.externals+    ++ WorkerWrapperFixResult.externals
+ src/HERMIT/Dictionary/AlphaConversion.hs view
@@ -0,0 +1,324 @@+{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}+module HERMIT.Dictionary.AlphaConversion+       ( -- * Alpha-Renaming and Shadowing+         externals+         -- ** Alpha-Renaming+       , alphaR+       , alphaLamR+       , alphaCaseBinderR+       , alphaAltWithR+       , alphaAltVarsR+       , alphaAltR+       , alphaCaseR+       , alphaLetWithR+       , alphaLetVarsR+       , alphaLetR+       , alphaProgConsWithR+         -- ** Shadow Detection and Unshadowing+       , unshadowR+       , visibleVarsT+       , freshNameGenT+       , freshNameGenAvoiding+       , replaceVarR+       )+where++import Control.Applicative+import Control.Arrow+import Control.Monad (liftM, liftM2)+import Data.Char (isDigit)+import Data.List (intersect)+import Data.Maybe (fromMaybe, listToMaybe)+import Data.Monoid++import HERMIT.Core+import HERMIT.Context+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC++import HERMIT.Dictionary.GHC hiding (externals)+import HERMIT.Dictionary.Common++import qualified Language.Haskell.TH as TH++import Prelude hiding (exp)++-----------------------------------------------------------------------++-- | Externals for alpha-renaming.+externals :: [External]+externals = map (.+ Deep)+         [  external "alpha" (alphaR :: RewriteH Core)+               [ "Renames the bound variables at the current node."]+         ,  external "alpha-lam" (promoteExprR . alphaLamR . Just :: TH.Name -> RewriteH Core)+               [ "Renames the bound variable in a Lambda expression to the given name."]+         ,  external "alpha-lam" (promoteExprR  (alphaLamR Nothing) :: RewriteH Core)+               [ "Renames the bound variable in a Lambda expression."]+         ,  external "alpha-case-binder" (promoteExprR . alphaCaseBinderR . Just :: TH.Name -> RewriteH Core)+               [ "Renames the binder in a Case expression to the given name."]+         ,  external "alpha-case-binder" (promoteExprR (alphaCaseBinderR Nothing) :: RewriteH Core)+               [ "Renames the binder in a Case expression."]+         ,  external "alpha-alt" (promoteAltR alphaAltR :: RewriteH Core)+               [ "Renames all binders in a Case alternative."]+         ,  external "alpha-alt" (promoteAltR . alphaAltWithR :: [TH.Name] -> RewriteH Core)+               [ "Renames all binders in a Case alternative using the user-provided list of new names."]+         ,  external "alpha-case" (promoteExprR alphaCaseR :: RewriteH Core)+               [ "Renames all binders in a Case alternative."]+         ,  external "alpha-let" (promoteExprR . alphaLetWithR :: [TH.Name] -> RewriteH Core)+               [ "Renames the bound variables in a Let expression using a list of suggested names."]+         ,  external "alpha-let" (promoteExprR alphaLetR :: RewriteH Core)+               [ "Renames the bound variables in a Let expression."]+         ,  external "alpha-top" (promoteProgR . alphaProgConsWithR :: [TH.Name] -> RewriteH Core)+               [ "Renames the bound identifiers in the top-level binding group at the head of the program using a list of suggested names."]+         -- ,  external "alpha-top" (promoteProgR alphaCons)+         --       [ "Renames the bound identifiers in the top-level binding at the head of the program."]+         -- ,  external "alpha-program" (promoteProgR alphaProg)+         --       [ "Renames identifiers bound at the top-level of the program."]+         ,  external "unshadow" (unshadowR :: RewriteH Core)+                [ "Rename local variables with manifestly unique names (x, x0, x1, ...)."]+         ]++-----------------------------------------------------------------------+--+-- freshNameGen is a function used in conjunction with cloneVarH, which clones an existing 'Var'.+-- But, what name should the new Id have?+-- cloneVarH generates a new Unique -- so we are positive that the new Var will be new,+-- but freshNameGen tries to assign a Name that will be meaningful to the user, and+-- not shadow other names in scope.+-- So,  we start with the name of the original Id, and add an integer suffix+--  x  goes to x0 or x1 or ...+-- and we do not want this newly generated name to shadow either:+-- 1.  Any free variable name in the active Expr; or+-- 2.  Any bound variables in context.++-- | List all visible identifiers (in the expression or the context).+visibleVarsT :: (BoundVars c, Monad m) => Translate c m CoreExpr VarSet+visibleVarsT = liftM2 unionVarSet boundVarsT (arr freeVarsExpr)++-- | If a name is provided replace the string with that,+--   otherwise modify the string making sure to /not/ clash with any visible variables.+freshNameGenT :: (BoundVars c, Monad m) => Maybe TH.Name -> Translate c m CoreExpr (String -> String)+freshNameGenT mn = freshNameGenAvoiding mn `liftM` visibleVarsT++-- | Use the optional argument if given, otherwise generate a new name avoiding clashes with the list of variables.+freshNameGenAvoiding :: Maybe TH.Name -> VarSet -> (String -> String)+freshNameGenAvoiding mn vs str = maybe (inventNames vs str) TH.nameBase mn++-- | Invent a new String based on the old one, but avoiding clashing with the given list of identifiers.+inventNames :: VarSet -> String -> String+inventNames curr old = head+                     [ nm+                     | nm <- old : [ base ++ show uq | uq <- [start ..] :: [Int] ]+                     , nm `notElem` names+                     ]+   where+           names = map uqName (varSetElems curr)+           nums = reverse $ takeWhile isDigit (reverse old)+           baseLeng = length $ drop (length nums) old+           base = take baseLeng old+           start = case reads nums of+                     [(v,_)] -> v + 1+                     _       -> 0+++-- | Remove all variables from the first set that shadow a variable in the second set.+shadowedBy :: VarSet -> VarSet -> VarSet+shadowedBy vs fvs = let fvUqNames = map uqName (varSetElems fvs)+                     in filterVarSet (\ v -> uqName v `elem` fvUqNames) vs++-- | Lifted version of 'shadowedBy'.+--   Additionally, it fails if no shadows are found.+shadowedByT :: MonadCatch m => Translate c m a VarSet -> Translate c m a VarSet -> Translate c m a VarSet+shadowedByT t1 t2 = setFailMsg "No shadows detected." $ (liftM2 shadowedBy t1 t2) >>> acceptR (not . isEmptyVarSet)++-- | Rename local variables with manifestly unique names (x, x0, x1, ...).+--   Does not rename top-level definitions.+unshadowR :: forall c. (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core+unshadowR = setFailMsg "No shadows to eliminate." $+           anytdR (promoteExprR unshadowExpr <+ promoteAltR unshadowAlt)++  where+    unshadowExpr :: Rewrite c HermitM CoreExpr+    unshadowExpr = do vs <- shadowedByT (mkVarSet <$> (letVarsT <+ (return <$> (caseWildIdT <+ lamVarT))))+                                        (unionVarSet <$> boundVarsT <*> arr freeVarsExpr)+                      alphaLamR Nothing <+ alphaLetVarsR (varSetElems vs) <+ alphaCaseBinderR Nothing++    unshadowAlt :: Rewrite c HermitM CoreAlt+    unshadowAlt = do vs <- shadowedByT (arr (mkVarSet . altVars))+                                       (unionVarSet <$> boundVarsT <*> arr freeVarsAlt)+                     alphaAltVarsR (varSetElems vs)++-----------------------------------------------------------------------++-- Maybe this should be defined elsewhere.++-- | Replace all occurrences of a specified variable.+--   Arguments are the variable to replace and the replacement variable, respectively.+replaceVarR :: (ExtendPath c Crumb, AddBindings c, Injection a Core, MonadCatch m) => Var -> Var -> Rewrite c m a+replaceVarR v v' = extractR $ tryR $ substR v $ varToCoreExpr v'++-- | Given a variable to replace, and a replacement, produce a 'Var' @->@ 'Var' function that+--   acts as an identity for all 'Var's except the one to replace, for which it returns the replacment.+--   Don't export this, it'll likely just cause confusion.+replaceVar :: Var -> Var -> (Var -> Var)+replaceVar v v' = replaceVars [(v,v')]++-- | Given a lists of variables to replace, and their replacements, produce a 'Var' @->@ 'Var' function that+--   acts as in identity for all 'Var's except the ones to replace, for which it returns the replacment.+--   Don't export this, it'll likely just cause confusion.+replaceVars :: [(Var,Var)] -> (Var -> Var)+replaceVars kvs v = fromMaybe v (lookup v kvs)++-----------------------------------------------------------------------++-- | Alpha rename a lambda binder.  Optionally takes a suggested new name.+alphaLamR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Rewrite c HermitM CoreExpr+alphaLamR mn = setFailMsg (wrongFormForAlpha "Lam v e") $+              do (v, nameModifier) <- lamT idR (freshNameGenT mn) (,)+                 v' <- constT (cloneVarH nameModifier v)+                 lamAnyR (arr $ replaceVar v v') (replaceVarR v v')++-----------------------------------------------------------------------++-- | Alpha rename a case binder.  Optionally takes a suggested new name.+alphaCaseBinderR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Rewrite c HermitM CoreExpr+alphaCaseBinderR mn = setFailMsg (wrongFormForAlpha "Case e v ty alts") $+                     do Case _ v _ _ <- idR+                        nameModifier <- freshNameGenT mn+                        v' <- constT (cloneVarH nameModifier v)+                        caseAnyR idR (return v') idR (\ _ -> replaceVarR v v')++-----------------------------------------------------------------------++-- | Rename the specified variable in a case alternative.  Optionally takes a suggested new name.+alphaAltVarR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Var -> Rewrite c HermitM CoreAlt+alphaAltVarR mn v =+  do nameModifier <- altT idR (\ _ -> idR) (freshNameGenT mn) (\ _ _ nameGen -> nameGen)+     v' <- constT (cloneVarH nameModifier v)+     altAnyR (fail "") (\ _ -> arr (replaceVar v v')) (replaceVarR v v')++-- | Rename the specified variables in a case alternative, using the suggested names where provided.+alphaAltVarsWithR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [(Maybe TH.Name,Var)] -> Rewrite c HermitM CoreAlt+alphaAltVarsWithR = andR . map (uncurry alphaAltVarR)++-- | Rename the variables bound in a case alternative with the given list of suggested names.+alphaAltWithR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [TH.Name] -> Rewrite c HermitM CoreAlt+alphaAltWithR ns =+  do vs <- arr altVars+     alphaAltVarsWithR $ zip (map Just ns) vs++-- | Rename the specified variables in a case alternative.+alphaAltVarsR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreAlt+alphaAltVarsR vs =+  do bs <- arr altVars+     alphaAltVarsWithR (zip (repeat Nothing) (bs `intersect` vs))++-- | Rename all identifiers bound in a case alternative.+alphaAltR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreAlt+alphaAltR = arr altVars >>= alphaAltVarsR++-----------------------------------------------------------------------++-- | Rename all identifiers bound in a case expression.+alphaCaseR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+alphaCaseR = alphaCaseBinderR Nothing >+> caseAllR idR idR idR (const alphaAltR)++-----------------------------------------------------------------------++-- | Alpha rename a non-recursive let binder.  Optionally takes a suggested new name.+alphaLetNonRecR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Rewrite c HermitM CoreExpr+alphaLetNonRecR mn = setFailMsg (wrongFormForAlpha "Let (NonRec v e1) e2") $+                    do (v, nameModifier) <- letNonRecT idR mempty (freshNameGenT mn) (\ v () nameMod -> (v, nameMod))+                       v' <- constT (cloneVarH nameModifier v)+                       letNonRecAnyR (return v') idR (replaceVarR v v')++-- | Alpha rename a non-recursive let binder if the variable appears in the argument list.  Optionally takes a suggested new name.+alphaLetNonRecVarsR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> [Var] -> Rewrite c HermitM CoreExpr+alphaLetNonRecVarsR mn vs = whenM ((`elem` vs) <$> letNonRecVarT) (alphaLetNonRecR mn)++-- | Rename the specified identifier bound in a recursive let.  Optionally takes a suggested new name.+alphaLetRecIdR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Id -> Rewrite c HermitM CoreExpr+alphaLetRecIdR mn v = setFailMsg (wrongFormForAlpha "Let (Rec bs) e") $+                     do usedVars <- unionVarSet <$> boundVarsT+                                                <*> letRecT (\ _ -> defT idR (arr freeVarsExpr) (flip extendVarSet)) (arr freeVarsExpr) (\ bndfvs vs -> unionVarSets (vs:bndfvs))+                        v' <- constT (cloneVarH (freshNameGenAvoiding mn usedVars) v)+                        letRecDefAnyR (\ _ -> (arr (replaceVar v v'), replaceVarR v v')) (replaceVarR v v')++-- | Rename the specified identifiers in a recursive let, using the suggested names where provided.+alphaLetRecIdsWithR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [(Maybe TH.Name,Id)] -> Rewrite c HermitM CoreExpr+alphaLetRecIdsWithR = andR . map (uncurry alphaLetRecIdR)++-- | Rename the identifiers bound in a Let with the given list of suggested names.+alphaLetWithR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [TH.Name] -> Rewrite c HermitM CoreExpr+alphaLetWithR ns = alphaLetNonRecR (listToMaybe ns)+                  <+ (letRecIdsT >>= (alphaLetRecIdsWithR . zip (map Just ns)))++-- | Rename the specified variables bound in a let.+alphaLetVarsR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreExpr+alphaLetVarsR vs = alphaLetNonRecVarsR Nothing vs+                   <+ (do bs <- letT (arr bindVars) successT const+                          alphaLetRecIdsWithR (zip (repeat Nothing) (bs `intersect` vs))+                      )++-- | Rename all identifiers bound in a Let.+alphaLetR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+alphaLetR = letVarsT >>= alphaLetVarsR++-----------------------------------------------------------------------++-- | Alpha rename a non-recursive top-level binder.  Optionally takes a suggested new name.+alphaProgConsNonRecR :: (ExtendPath c Crumb, AddBindings c) => TH.Name -> Rewrite c HermitM CoreProg+alphaProgConsNonRecR n = setFailMsg (wrongFormForAlpha "ProgCons (NonRec v e) p") $+                    do ProgCons (NonRec v _) _ <- idR+                       v' <- constT (cloneVarH (\ _ -> TH.nameBase n) v)+                       consNonRecAnyR (return v') idR (replaceVarR v v')++-- -- | Alpha rename a non-recursive top-level binder if the identifier appears in the argument list.  Optionally takes a suggested new name.+-- alphaConsNonRecIds :: Maybe TH.Name -> [Id] -> Rewrite c m CoreProg+-- alphaConsNonRecIds mn vs = whenM ((`elem` vs) <$> consNonRecIdT) (alphaConsNonRec mn)++-- | Rename the specified identifier bound in a recursive top-level binder.  Optionally takes a suggested new name.+alphaProgConsRecIdR :: (ExtendPath c Crumb, AddBindings c) => TH.Name -> Id -> Rewrite c HermitM CoreProg+alphaProgConsRecIdR n v =  setFailMsg (wrongFormForAlpha "ProgCons (Rec bs) p") $+                      do v' <- constT (cloneVarH (\ _ -> TH.nameBase n) v)+                         consRecDefAnyR (\ _ -> (arr (replaceVar v v'), replaceVarR v v')) (replaceVarR v v')++-- | Rename the specified identifiers in a recursive top-level binding at the head of a program, using the suggested names where provided.+alphaProgConsRecIdsWithR :: (ExtendPath c Crumb, AddBindings c) => [(TH.Name,Id)] -> Rewrite c HermitM CoreProg+alphaProgConsRecIdsWithR = andR . map (uncurry alphaProgConsRecIdR)++-- | Rename the identifiers bound in the top-level binding at the head of the program with the given list of suggested names.+alphaProgConsWithR :: (ExtendPath c Crumb, AddBindings c) => [TH.Name] -> Rewrite c HermitM CoreProg+alphaProgConsWithR []     = fail "At least one new name must be provided."+alphaProgConsWithR (n:ns) = alphaProgConsNonRecR n <+ (progConsRecIdsT >>= (alphaProgConsRecIdsWithR . zip (n:ns)))++-- -- | Rename the specified variables bound in the top-level binding at the head of the program.+-- alphaConsIds :: [Id] -> Rewrite c m CoreProg+-- alphaConsIds vs = alphaConsNonRecIds Nothing vs <+ alphaConsRecIdsWith (zip (repeat Nothing) vs)++-- -- | Rename all identifiers bound in the top-level binding at the head of the program.+-- alphaCons :: Rewrite c m CoreProg+-- alphaCons = consIdsT >>= alphaConsIds++-----------------------------------------------------------------------++-- -- | Rename all identifiers bound at the top-level.+-- alphaProg :: Rewrite c m CoreProg+-- alphaProg = progNilT ProgNil <+ (alphaCons >>> progConsAllR idR alphaProg)++-----------------------------------------------------------------------++-- | Alpha rename any bindings at this node.  Note: does not rename case alternatives unless invoked on the alternative.+alphaR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core+alphaR = setFailMsg "Cannot alpha-rename here." $+           promoteExprR (alphaLamR Nothing <+ alphaCaseBinderR Nothing <+ alphaLetR)+        <+ promoteAltR alphaAltR++-----------------------------------------------------------------------++wrongFormForAlpha :: String -> String+wrongFormForAlpha s = "Cannot alpha-rename, " ++ wrongExprForm s++-----------------------------------------------------------------------
+ src/HERMIT/Dictionary/Common.hs view
@@ -0,0 +1,251 @@+{-# LANGUAGE CPP, ScopedTypeVariables, FlexibleContexts, LambdaCase #-}++-- | Note: this module should NOT export externals. It is for common+--   transformations needed by the other primitive modules.+module HERMIT.Dictionary.Common+    ( -- * Utility Transformations+      applyInContextT+      -- ** Finding function calls.+    , callT+    , callPredT+    , callNameT+    , callSaturatedT+    , callNameG+    , callDataConT+    , callDataConNameT+    , callsR+    , callsT+      -- ** Collecting variable bindings+    , progConsIdsT+    , progConsRecIdsT+    , progConsNonRecIdT+    , nonRecVarT+    , recIdsT+    , lamVarT+    , letVarsT+    , letRecIdsT+    , letNonRecVarT+    , caseVarsT+    , caseWildIdT+    , caseAltVarsT+      -- ** Finding variables bound in the Context+    , boundVarsT+    , findBoundVarT+    , findIdT+    , findId+    , varBindingDepthT+    , varIsOccurrenceOfT+    , exprIsOccurrenceOfT+      -- Miscellaneous+    , wrongExprForm+    )++where++import Data.List+import Data.Monoid++import Control.Arrow++import HERMIT.Kure+import HERMIT.Core+import HERMIT.Context+import HERMIT.GHC++import qualified Language.Haskell.TH as TH++------------------------------------------------------------------------------++-- | Apply a transformation to a value in the current context.+applyInContextT :: Translate c m a b -> a -> Translate c m x b+applyInContextT t a = contextonlyT $ \ c -> apply t c a++-- Note: this is the same as: return a >>> t++------------------------------------------------------------------------------++-- | Lift GHC's collectArgs+callT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])+callT = contextfreeT $ \ e -> case e of+                                Var {} -> return (e, [])+                                App {} -> return (collectArgs e)+                                _      -> fail "not an application or variable occurence."++callPredT :: Monad m => (Id -> [CoreExpr] -> Bool) -> Translate c m CoreExpr (CoreExpr, [CoreExpr])+callPredT p = do+    call@(Var i, args) <- callT+    guardMsg (p i args) "predicate failed."+    return call++-- | Succeeds if we are looking at an application of given function+--   returning zero or more arguments to which it is applied.+callNameT :: MonadCatch m => TH.Name -> Translate c m CoreExpr (CoreExpr, [CoreExpr])+callNameT nm = setFailMsg ("callNameT failed: not a call to '" ++ show nm ++ ".") $+    callPredT (const . cmpTHName2Var nm)++-- | Succeeds if we are looking at a fully saturated function call.+callSaturatedT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])+callSaturatedT = callPredT (\ i args -> idArity i == length args)+-- TODO: probably better to calculate arity based on Id's type, as+--       idArity is conservatively set to zero by default.++-- | Succeeds if we are looking at an application of given function+callNameG :: MonadCatch m => TH.Name -> Translate c m CoreExpr ()+callNameG nm = prefixFailMsg "callNameG failed: " $ callNameT nm >>= \_ -> constT (return ())++-- | Succeeds if we are looking at an application of a data constructor.+callDataConT :: MonadCatch m => Translate c m CoreExpr (DataCon, [Type], [CoreExpr])+callDataConT = prefixFailMsg "callDataConT failed:" $+#if __GLASGOW_HASKELL__ > 706+    do mb <- contextfreeT $ \ e -> let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- varSetElems (localFreeVarsExpr e) ])+                                   in return $ exprIsConApp_maybe (in_scope, idUnfolding) e+       maybe (fail "not a datacon application.") return mb+#else+    contextfreeT (return . exprIsConApp_maybe idUnfolding)+        >>= maybe (fail "not a datacon application.") return+#endif++-- | Succeeds if we are looking at an application of a named data constructor.+callDataConNameT :: MonadCatch m => TH.Name -> Translate c m CoreExpr (DataCon, [Type], [CoreExpr])+callDataConNameT nm = do+    res@(dc,_,_) <- callDataConT+    guardMsg (cmpTHName2Name nm (dataConName dc)) "wrong datacon."+    return res++-- | Apply a rewrite to all applications of a given function in a top-down manner, pruning on success.+callsR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Rewrite c m CoreExpr -> Rewrite c m Core+callsR nm rr = prunetdR (promoteExprR $ callNameG nm >> rr)++-- | Apply a translate to all applications of a given function in a top-down manner,+--   pruning on success, collecting the results.+callsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Translate c m CoreExpr b -> Translate c m Core [b]+callsT nm t = collectPruneT (promoteExprT $ callNameG nm >> t)++------------------------------------------------------------------------------++-- | List the identifiers bound by the top-level binding group at the head of the program.+progConsIdsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreProg [Id]+progConsIdsT = progConsT (arr bindVars) mempty (\ vs () -> vs)++-- | List the identifiers bound by a recursive top-level binding group at the head of the program.+progConsRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg [Id]+progConsRecIdsT = progConsT recIdsT mempty (\ vs () -> vs)++-- | Return the identifier bound by a non-recursive top-level binding at the head of the program.+progConsNonRecIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg Id+progConsNonRecIdT = progConsT nonRecVarT mempty (\ v () -> v)++-- | Return the variable bound by a non-recursive let expression.+nonRecVarT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreBind Var+nonRecVarT = nonRecT idR mempty (\ v () -> v)++-- | List all identifiers bound in a recursive binding group.+recIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind [Id]+recIdsT = recT (\ _ -> arr defId) id++-- | Return the variable bound by a lambda expression.+lamVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var+lamVarT = lamT idR mempty (\ v () -> v)++-- | List the variables bound by a let expression.+letVarsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreExpr [Var]+letVarsT = letT (arr bindVars) mempty (\ vs () -> vs)++-- | List the identifiers bound by a recursive let expression.+letRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Id]+letRecIdsT = letT recIdsT mempty (\ vs () -> vs)++-- | Return the variable bound by a non-recursive let expression.+letNonRecVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var+letNonRecVarT = letT nonRecVarT mempty (\ v () -> v)++-- | List all variables bound by a case expression (in the alternatives and the wildcard binder).+caseVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Var]+caseVarsT = caseT mempty idR mempty (\ _ -> arr altVars) (\ () v () vss -> v : nub (concat vss))++-- | Return the case wildcard binder.+caseWildIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Id+caseWildIdT = caseT mempty idR mempty (\ _ -> idR) (\ () i () _ -> i)++-- | List the variables bound by all alternatives in a case expression.+caseAltVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [[Var]]+caseAltVarsT = caseT mempty mempty mempty (\ _ -> arr altVars) (\ () () () vss -> vss)++------------------------------------------------------------------------------++-- | Find the depth of a variable's binding.+varBindingDepthT :: (ReadBindings c, Monad m) => Var -> Translate c m g BindingDepth+varBindingDepthT v = contextT >>= lookupHermitBindingDepth v++-- | Determine if the current variable matches the given variable, and is bound at the specified depth (helpful to detect shadowing).+varIsOccurrenceOfT :: (ExtendPath c Crumb, ReadBindings c, Monad m) => Var -> BindingDepth -> Translate c m Var Bool+varIsOccurrenceOfT v d = readerT $ \ v' -> if v == v'+                                             then varBindingDepthT v >>^ (== d)+                                             else return False++-- | Determine if the current expression is an occurrence of the given variable, bound at the specified depth (helpful to detect shadowing).+exprIsOccurrenceOfT :: (ExtendPath c Crumb, ReadBindings c, Monad m) => Var -> BindingDepth -> Translate c m CoreExpr Bool+exprIsOccurrenceOfT v d = varT $ varIsOccurrenceOfT v d++-- | Lifted version of 'boundVars'.+boundVarsT :: (BoundVars c, Monad m) => Translate c m a VarSet+boundVarsT = contextonlyT (return . boundVars)++-- | Find the unique variable bound in the context that matches the given name, failing if it is not unique.+findBoundVarT :: (BoundVars c, MonadCatch m) => TH.Name -> Translate c m a Var+findBoundVarT nm = prefixFailMsg ("Cannot resolve name " ++ show nm ++ ", ") $+                        do c <- contextT+                           case varSetElems (findBoundVars nm c) of+                             []         -> fail "no matching variables in scope."+                             [v]        -> return v+                             _ : _ : _  -> fail "multiple matching variables in scope."++-- | Lookup the name in the context first, then, failing that, in GHC's global reader environment.+findIdT :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m, MonadCatch m) => TH.Name -> Translate c m a Id+findIdT nm = prefixFailMsg ("Cannot resolve name " ++ show nm ++ ", ") $+             contextonlyT (findId nm)++findId :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m) => TH.Name -> c -> m Id+findId nm c = case varSetElems (findBoundVars nm c) of+                []         -> findIdMG nm c+                [v]        -> return v+                _ : _ : _  -> fail "multiple matching variables in scope."++findIdMG :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m) => TH.Name -> c -> m Id+findIdMG nm c =+    case filter isValName $ findNamesFromTH (hermitGlobalRdrEnv c) nm of+      []  -> findIdBuiltIn nm+      [n] -> lookupId n+      ns  -> do dynFlags <- getDynFlags+                fail $ "multiple matches found:\n" ++ intercalate ", " (map (showPpr dynFlags) ns)++findIdBuiltIn :: forall m. Monad m => TH.Name -> m Id+findIdBuiltIn = go . show+    where go ":"     = dataConId consDataCon+          go "[]"    = dataConId nilDataCon++          go "True"  = return trueDataConId+          go "False" = return falseDataConId++          go "<"     = return ltDataConId+          go "=="    = return eqDataConId+          go ">"     = return gtDataConId++          go "I#"    = dataConId intDataCon++          go "()"    = return unitDataConId+          -- TODO: add more as needed+          --       http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/TysWiredIn.html+          go _   = fail "variable not in scope."++          dataConId :: DataCon -> m Id+          dataConId = return . dataConWorkId++------------------------------------------------------------------------------++-- | Constructs a common error message.+--   Argument 'String' should be the desired form of the expression.+wrongExprForm :: String -> String+wrongExprForm form = "Expression does not have the form: " ++ form++------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Composite.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}++module HERMIT.Dictionary.Composite+    ( externals+    , unfoldBasicCombinatorR+    , simplifyR+    , bashUsingR+    , bashR+    , bashExtendedWithR+    , bashDebugR+    )+where++import Control.Arrow++import HERMIT.Context+import HERMIT.Core+import HERMIT.GHC+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External++import HERMIT.Dictionary.Debug hiding (externals)+import HERMIT.Dictionary.GHC hiding (externals)+import HERMIT.Dictionary.Inline hiding (externals)+import HERMIT.Dictionary.Local hiding (externals)+import HERMIT.Dictionary.Unfold hiding (externals)++import qualified Language.Haskell.TH as TH++------------------------------------------------------------------------------------------------------++externals ::  [External]+externals =+    [ external "unfold-basic-combinator" (promoteExprR unfoldBasicCombinatorR :: RewriteH Core)+        [ "Unfold the current expression if it is one of the basic combinators: ($), (.), id, flip, const, fst or snd." ]+    , external "simplify" (simplifyR :: RewriteH Core)+        [ "innermost (unfold-basic-combinator <+ beta-reduce-plus <+ safe-let-subst <+ case-reduce <+ let-elim)" ]+    , external "bash" (bashR :: RewriteH Core)+        bashHelp .+ Eval .+ Deep .+ Loop+    , external "bash-extended-with" (bashExtendedWithR :: [RewriteH Core] -> RewriteH Core)+        [ "Run \"bash\" extended with an additional rewrite.",+          "Note: be sure that the new rewrite either fails or makes progress, else this may loop."+        ] .+ Eval .+ Deep .+ Loop+    , external "bash-debug" (bashDebugR :: RewriteH Core)+        [ "verbose bash - most useful with set-auto-corelint True" ] .+ Eval .+ Deep .+ Loop+    ]++------------------------------------------------------------------------------------------------------++basicCombinators :: [String]+basicCombinators = ["$",".","id","flip","const","fst","snd","curry","uncurry"]++-- | Unfold the current expression if it is one of the basic combinators: ('$'), ('.'), 'id', 'flip', 'const', 'fst' or 'snd'.+--   This is intended to be used as a component of simplification traversals such as 'simplifyR' or 'bashR'.+unfoldBasicCombinatorR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+unfoldBasicCombinatorR = setFailMsg "unfold-basic-combinator failed." $+     unfoldNamesR (map TH.mkName basicCombinators)++simplifyR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM Core+simplifyR = setFailMsg "Simplify failed: nothing to simplify." $+    innermostR (   promoteBindR recToNonrecR+                <+ promoteExprR ( unfoldBasicCombinatorR+                               <+ betaReducePlusR+                               <+ letNonRecSubstSafeR+                               <+ caseReduceR+                               <+ letElimR )+               )++------------------------------------------------------------------------------------------------------++bashR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM Core+bashR = bashUsingR (map fst bashComponents)++bashExtendedWithR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [Rewrite c HermitM Core] -> Rewrite c HermitM Core+bashExtendedWithR rs = bashUsingR (rs ++ map fst bashComponents)++bashDebugR :: RewriteH Core+bashDebugR = bashUsingR $ map (\ (r,nm) -> r >>> observeR nm) bashComponents++-- bashUsingR :: forall c m. (ExtendPath c Crumb, AddBindings c, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core+-- bashUsingR rs =+--     setFailMsg "bash failed: nothing to do." $+--     readerT $ \ core1 -> occurAnalyseR >>> readerT (\ core2 -> if core1 `coreSyntaxEq` core2+--                                                                  then bashCoreR      -- equal, no progress yet+--                                                                  else tryR bashCoreR -- unequal, progress has already been made+--                                                    )+--   -- the changedByR combinator doesn't quite do what we need here+--   where+--     bashCoreR :: Rewrite c m Core+--     bashCoreR = repeatR (innermostR (catchesT rs) >>> occurAnalyseR)++bashUsingR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => [Rewrite c m Core] -> Rewrite c m Core+bashUsingR rs =+    setFailMsg "bash failed: nothing to do." $+    repeatR (occurAnalyseR >>> onetdR (catchesT rs)) >+> anytdR (promoteExprR dezombifyR) >+> occurAnalyseChangedR++ --   occurAnalyseChangedR >+> (innermostR (catchesT rs) >>> occurAnalyseR)++{-+Occurrence Analysis updates meta-data, as well as performing some basic simplifications.+occurAnalyseR always succeeds, whereas occurAnalyseChangedR fails is the result is syntactically equivalent.+The awkwardness is because:+  - we want bash to fail if nothing changes+  - we want bash to succeed if the result is not syntactically-equivalent (ideally, if any changes are made at all, but that's not the case yet)+  - we want bash to update the meta-data+  - after running bash there should be nothing left to do (i.e. an immediately subsequent bash should always fail)++Also, it's still possible for some meta-data to be out-of-date after bash, despite the case analysis.  For example, if the focal point is a case-alt rhs, this won't update the identifer info of variables bound in the alternative.+-}++bashHelp :: [String]+bashHelp = "Iteratively apply the following rewrites until nothing changes:" : map snd (bashComponents+                                                                                         :: [(RewriteH Core,String)] -- to resolve ambiguity+                                                                                       )++-- TODO: Think about a good order for bash.+bashComponents :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [(Rewrite c HermitM Core, String)]+bashComponents =+  [ -- (promoteExprR occurAnalyseExprChangedR, "occur-analyse-expr")    -- ??+    (promoteExprR betaReduceR, "beta-reduce")                        -- O(1)+  , (promoteExprR caseReduceR, "case-reduce")                        -- O(n)+  , (promoteExprR caseReduceIdR, "case-reduce-id")                   -- O(n)+  , (promoteExprR caseElimSeqR, "case-elim-seq")+  , (promoteExprR unfoldBasicCombinatorR, "unfold-basic-combinator") -- O(n)+  , (promoteExprR inlineCaseAlternativeR, "inline-case-alternative") -- O(n)+  , (promoteExprR etaReduceR, "eta-reduce")                          -- O(n)+--  , (promoteBindR recToNonrecR, "rec-to-nonrec")                     -- O(n) -- subsumed by occurrence analysis+  , (promoteExprR letNonRecSubstSafeR, "let-nonrec-subst-safe")      -- O(n)+  , (promoteExprR caseFloatAppR, "case-float-app")                   -- O(n)+  , (promoteExprR caseFloatCaseR, "case-float-case")                 -- O(n)+  , (promoteExprR caseFloatLetR, "case-float-let")                   -- O(n) but usually O(1)+  , (promoteExprR caseFloatCastR, "case-float-cast")                 -- O(1)+--  , (promoteExprR letElimR, "let-elim")  -- O(n^2) -- Subsumed by occurrence analysis.+  , (promoteExprR letFloatAppR, "let-float-app")                     -- O(n)+  , (promoteExprR letFloatArgR, "let-float-arg")                     -- O(n)+  , (promoteExprR letFloatLamR, "let-float-lam")                     -- O(n)+  , (promoteExprR letFloatLetR, "let-float-let")                     -- O(n)+  , (promoteExprR letFloatCaseR, "let-float-case")                   -- O(n)+  , (promoteExprR letFloatCastR, "let-float-cast")                   -- O(1)+  , (promoteProgR letFloatTopR, "let-float-top")                     -- O(n)+  , (promoteExprR castElimReflR, "cast-elim-refl")                   -- O(1)+  , (promoteExprR castElimSymR, "cast-elim-sym")                     -- O(1)+--  , (promoteExprR dezombifyR, "dezombify")                           -- O(1) -- performed at the end+  ]++------------------------------------------------------------------------------------------------------+
+ src/HERMIT/Dictionary/Debug.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE FlexibleContexts #-}+module HERMIT.Dictionary.Debug+       ( -- * Debugging Dictionarys+         externals+       , bracketR+       , observeR+       , observeFailureR+       , traceR+       )+where++import Control.Arrow++import HERMIT.Kure+import HERMIT.External+import HERMIT.Monad++-- | Exposed debugging 'External's.+externals :: [External]+externals = map (.+ Debug)+         [ external "trace" (traceR :: String -> RewriteH Core)+                [ "give a side-effect message as output when processing this command" ]+         , external "observe" (observeR :: String -> RewriteH Core)+                [ "give a side-effect message as output, and observe the value being processed" ]+         , external "observe-failure" (observeFailureR :: String -> RewriteH Core -> RewriteH Core)+                [ "give a side-effect message if the rewrite fails, including the failing input" ]+         , external "bracket" (bracketR :: String -> RewriteH Core -> RewriteH Core)+                [ "if given rewrite succeeds, see its input and output" ]+         ]++-- | If the 'Rewrite' fails, print out the 'Core', with a message.+observeFailureR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a+observeFailureR str m = m <+ observeR str++-- | Print out the 'Core', with a message.+observeR :: Injection a CoreTC => String -> RewriteH a+observeR msg = extractR $ sideEffectR $ \ cxt core ->+        sendDebugMessage $ DebugCore msg cxt core++-- | Just say something, every time the rewrite is done.+traceR :: String -> RewriteH a+traceR msg = sideEffectR $ \ _ _ -> sendDebugMessage $ DebugTick msg++-- | Show before and after a rewrite.+bracketR :: Injection a CoreTC => String -> RewriteH a -> RewriteH a+bracketR msg rr = do+    -- Be careful to only run the rr once, in case it has side effects.+    (e,r) <- idR &&& attemptM rr+    either fail (\ e' -> do _ <- return e >>> observeR before+                            return e' >>> observeR after) r+    where before = msg ++ " (before)"+          after  = msg ++ " (after)"+-- attemptM :: MonadCatch m => m a -> m (Either String a)
+ src/HERMIT/Dictionary/FixPoint.hs view
@@ -0,0 +1,208 @@+{-# LANGUAGE ScopedTypeVariables #-}++module HERMIT.Dictionary.FixPoint+       ( -- * Operations on the Fixed Point Operator (fix)+         -- | Note that many of these operations require 'Data.Function.fix' to be explicitly imported, if it is not used in the source file.+         HERMIT.Dictionary.FixPoint.externals+         -- ** Rewrites and BiRewrites on Fixed Points+       , fixIntroR+       , fixComputationRuleBR+       , fixRollingRuleBR+       , fixFusionRuleBR+         -- ** Utilities+       , mkFixT+       , isFixExprT+       )+where++import Control.Applicative+import Control.Arrow++import Data.Monoid (mempty)++import HERMIT.Context+import HERMIT.Core+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC+import HERMIT.ParserCore+import HERMIT.Utilities++import HERMIT.Dictionary.Common+import HERMIT.Dictionary.GHC+import HERMIT.Dictionary.Reasoning+import HERMIT.Dictionary.Undefined++import qualified Language.Haskell.TH as TH++--------------------------------------------------------------------------------------------------++-- | Externals for manipulating fixed points.+externals ::  [External]+externals =+         [ external "fix-intro" (promoteDefR fixIntroR :: RewriteH Core)+                [ "rewrite a recursive binding into a non-recursive binding using fix"+                ] .+ Introduce .+ Context+         , external "fix-computation-rule" (promoteExprBiR fixComputationRuleBR :: BiRewriteH Core)+                [ "Fixed-Point Computation Rule",+                  "fix t f  <==>  f (fix t f)"+                ] .+ Context+         , external "fix-rolling-rule" (promoteExprBiR fixRollingRuleBR :: BiRewriteH Core)+                [ "Rolling Rule",+                  "fix tyA (\\ a -> f (g a))  <==>  f (fix tyB (\\ b -> g (f b))"+                ] .+ Context+         , external "fix-fusion-rule" ((\ f g h lhsR rhsR strictf -> promoteExprBiR (fixFusionRule (Just (lhsR,rhsR)) (Just strictf) f g h)) :: CoreString -> CoreString -> CoreString -> RewriteH Core -> RewriteH Core -> RewriteH Core -> BiRewriteH Core)+                [ "Fixed-point Fusion Rule"+                , "Given f :: A -> B, g :: A -> A, h :: B -> B, and"+                , "proofs that, for some x, (f (g a) ==> x) and (h (f a) ==> x) and that f is strict, then"+                , "f (fix g) <==> fix h"+                ] .+ Context+         , external "fix-fusion-rule-unsafe" ((\ f g h lhsR rhsR -> promoteExprBiR (fixFusionRule (Just (lhsR,rhsR)) Nothing f g h)) :: CoreString -> CoreString -> CoreString -> RewriteH Core -> RewriteH Core -> BiRewriteH Core)+                [ "(Unsafe) Fixed-point Fusion Rule"+                , "Given f :: A -> B, g :: A -> A, h :: B -> B, and"+                , "a proof that, for some x, (f (g a) ==> x) and (h (f a) ==> x), then"+                , "f (fix g) <==> fix h"+                , "Note that the precondition that f is strict is required to hold."+                ] .+ Context .+ PreCondition+         , external "fix-fusion-rule-unsafe" ((\ f g h -> promoteExprBiR (fixFusionRule Nothing Nothing f g h)) :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)+                [ "(Very Unsafe) Fixed-point Fusion Rule"+                , "Given f :: A -> B, g :: A -> A, h :: B -> B, then"+                , "f (fix g) <==> fix h"+                , "Note that the preconditions that f (g a) == h (f a) and that f is strict are required to hold."+                ] .+ Context .+ PreCondition+         ]++--------------------------------------------------------------------------------------------------++-- |  @f = e@   ==\>   @f = fix (\\ f -> e)@+fixIntroR :: RewriteH CoreDef+fixIntroR = prefixFailMsg "fix introduction failed: " $+           do Def f _ <- idR+              f' <- constT $ cloneVarH id f+              Def f <$> (mkFixT =<< (defT mempty (extractR $ substR f $ varToCoreExpr f') (\ () e' -> Lam f' e')))++--------------------------------------------------------------------------------------------------++-- | @fix ty f@  \<==\>  @f (fix ty f)@+fixComputationRuleBR :: BiRewriteH CoreExpr+fixComputationRuleBR = bidirectional computationL computationR+  where+    computationL :: RewriteH CoreExpr+    computationL = prefixFailMsg "fix computation rule failed: " $+                   do (_,f) <- isFixExprT+                      fixf  <- idR+                      return (App f fixf)++    computationR :: RewriteH CoreExpr+    computationR = prefixFailMsg "(backwards) fix computation rule failed: " $+                   do App f fixf <- idR+                      (_,f') <- isFixExprT <<< constant fixf+                      guardMsg (exprAlphaEq f f') "external function does not match internal expression"+                      return fixf+++-- | @fix tyA (\\ a -> f (g a))@  \<==\>  @f (fix tyB (\\ b -> g (f b))@+fixRollingRuleBR :: BiRewriteH CoreExpr+fixRollingRuleBR = bidirectional rollingRuleL rollingRuleR+  where+    rollingRuleL :: RewriteH CoreExpr+    rollingRuleL = prefixFailMsg "rolling rule failed: " $+                   withPatFailMsg wrongFixBody $+                   do (tyA, Lam a (App f (App g (Var a')))) <- isFixExprT+                      guardMsg (a == a') wrongFixBody+                      (tyA',tyB) <- funsWithInverseTypes g f+                      guardMsg (eqType tyA tyA') "Type mismatch: this shouldn't have happened, report this as a bug."+                      res <- rollingRuleResult tyB g f+                      return (App f res)++    rollingRuleR :: RewriteH CoreExpr+    rollingRuleR = prefixFailMsg "(reversed) rolling rule failed: " $+                   withPatFailMsg "not an application." $+                   do App f fx <- idR+                      withPatFailMsg wrongFixBody $+                        do (tyB, Lam b (App g (App f' (Var b')))) <- isFixExprT <<< constant fx+                           guardMsg (b == b') wrongFixBody+                           guardMsg (exprAlphaEq f f') "external function does not match internal expression"+                           (tyA,tyB') <- funsWithInverseTypes g f+                           guardMsg (eqType tyB tyB') "Type mismatch: this shouldn't have happened, report this as a bug."+                           rollingRuleResult tyA f g++    rollingRuleResult :: Type -> CoreExpr -> CoreExpr -> TranslateH z CoreExpr+    rollingRuleResult ty f g = do x <- constT (newIdH "x" ty)+                                  mkFixT (Lam x (App f (App g (Var x))))++    wrongFixBody :: String+    wrongFixBody = "body of fix does not have the form: Lam v (App f (App g (Var v)))"++--------------------------------------------------------------------------------------------------++-- f :: A -> B+-- g :: A -> A+-- h :: B -> B++-- | If @f@ is strict, then (@f (g a)@ == @h (f a)@)  ==\>  (@f (fix g)@ == @fix h@)+fixFusionRuleBR :: Maybe (RewriteH CoreExpr, RewriteH CoreExpr) -> Maybe (RewriteH CoreExpr) -> CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr+fixFusionRuleBR meq mfstrict f g h = beforeBiR+  (prefixFailMsg "fixed-point fusion failed: " $+   do (tyA,tyB) <- funArgResTypes f+      tyA'      <- endoFunType g+      tyB'      <- endoFunType h+      guardMsg (typeAlphaEq tyA tyA' && typeAlphaEq tyB tyB') "given functions do not have compatible types."+      whenJust (verifyStrictT f) mfstrict+      whenJust (\ (lhsR,rhsR) ->+                  do a <- constT (newGlobalIdH "a" tyA)+                     let lhs = App f (App g (Var a))+                         rhs = App h (App f (Var a))+                     verifyEqualityCommonTargetT lhs rhs lhsR rhsR+               )+               meq+  )+  (\ () -> bidirectional fixFusionL fixFusionR)++     where+       fixFusionL :: RewriteH CoreExpr+       fixFusionL = prefixFailMsg "fixed-point fusion failed: " $+                    withPatFailMsg (wrongExprForm "App f (fix g)") $+                    do App f' fixg <- idR+                       guardMsg (exprAlphaEq f f') "first argument function does not match."+                       (_,g') <- isFixExprT <<< return fixg+                       guardMsg (exprAlphaEq g g') "second argument function does not match."+                       mkFixT h++       fixFusionR :: RewriteH CoreExpr+       fixFusionR = prefixFailMsg "(reversed) fixed-point fusion failed: " $+                    do (_,h') <- isFixExprT+                       guardMsg (exprAlphaEq h h') "third argument function does not match."+                       App f <$> mkFixT g++-- | If @f@ is strict, then (@f (g a)@ == @h (f a)@)  ==>  (@f (fix g)@ == @fix h@)+fixFusionRule :: Maybe (RewriteH Core, RewriteH Core) -> Maybe (RewriteH Core) -> CoreString -> CoreString -> CoreString -> BiRewriteH CoreExpr+fixFusionRule meq mfstrict = parse3beforeBiR $ fixFusionRuleBR ((extractR *** extractR) <$> meq) (extractR <$> mfstrict)++--------------------------------------------------------------------------------------------------++-- | Check that the expression has the form "fix t (f :: t -> t)", returning "t" and "f".+isFixExprT :: TranslateH CoreExpr (Type,CoreExpr)+isFixExprT = withPatFailMsg (wrongExprForm "fix t f") $ -- fix :: forall a. (a -> a) -> a+  do App (App (Var fixId) (Type ty)) f <- idR+     fixId' <- findFixId+     guardMsg (fixId == fixId') (var2String fixId ++ " does not match " ++ fixLocation)+     return (ty,f)++--------------------------------------------------------------------------------------------------++-- | f  ==>  fix f+mkFixT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => CoreExpr -> Translate c m z CoreExpr+mkFixT f = do t <- endoFunType f+              fixId <- findFixId+              return $ mkCoreApps (varToCoreExpr fixId) [Type t, f]++fixLocation :: String+fixLocation = "Data.Function.fix"++-- TODO: will crash if 'fix' is not used (or explicitly imported) in the source file.+findFixId :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Translate c m a Id+findFixId = findIdT (TH.mkName fixLocation)++--------------------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Fold.hs view
@@ -0,0 +1,174 @@+module HERMIT.Dictionary.Fold+    ( -- * Fold/Unfold Transformation+      externals+    , foldR+    , foldVarR+    , stashFoldR+    , stashFoldAnyR+    )++where++import Control.Arrow+import Control.Applicative+import Control.Monad++import Data.List (intercalate)+import qualified Data.Map as Map++import HERMIT.Core+import HERMIT.Context+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC++import HERMIT.Dictionary.Common (varBindingDepthT)+import HERMIT.Dictionary.GHC hiding (externals)+import HERMIT.Dictionary.Inline hiding (externals)++import qualified Language.Haskell.TH as TH++import Prelude hiding (exp)++------------------------------------------------------------------------++externals :: [External]+externals =+    [ external "fold" (promoteExprR . foldR :: TH.Name -> RewriteH Core)+        [ "fold a definition"+        , ""+        , "double :: Int -> Int"+        , "double x = x + x"+        , ""+        , "5 + 5 + 6"+        , "any-bu (fold 'double)"+        , "double 5 + 6"+        , ""+        , "Note: due to associativity, if you wanted to fold 5 + 6 + 6, "+        , "you first need to apply an associativity rewrite." ]  .+ Context .+ Deep+    , external "fold" (promoteExprR . stashFoldR :: Label -> RewriteH Core)+        [ "Fold a remembered definition." ]                      .+ Context .+ Deep+    , external "fold-any" (promoteExprR stashFoldAnyR :: RewriteH Core)+        [ "Attempt to fold any of the remembered definitions." ] .+ Context .+ Deep+    ]++------------------------------------------------------------------------++stashFoldR :: ReadBindings c => Label -> Rewrite c HermitM CoreExpr+stashFoldR label = prefixFailMsg "Fold failed: " $+    translate $ \ c e -> do+        Def i rhs <- lookupDef label+        guardMsg (inScope c i) $ var2String i ++ " is not in scope.\n(A common cause of this error is trying to fold a recursive call while being in the body of a non-recursive definition.  This can be resolved by calling \"nonrec-to-rec\" on the non-recursive binding group.)"+        maybe (fail "no match.")+              return+              (fold i rhs e)++stashFoldAnyR :: ReadBindings c => Rewrite c HermitM CoreExpr+stashFoldAnyR = setFailMsg "Fold failed: no definitions could be folded." $+                catchesM =<< map stashFoldR <$> (Map.keys <$> constT getStash)++foldR :: ReadBindings c => TH.Name -> Rewrite c HermitM CoreExpr+foldR nm = prefixFailMsg "Fold failed: " $+           do c <- contextT+              case varSetElems (findBoundVars nm c) of+                []  -> fail "cannot find name."+                [v] -> foldVarR v Nothing+                vs  -> fail $ "multiple names match: " ++ intercalate ", " (map var2String vs)++foldVarR :: ReadBindings c => Var -> Maybe BindingDepth -> Rewrite c HermitM CoreExpr+foldVarR v md =+             do case md of+                  Nothing    -> return ()+                  Just depth -> do depth' <- varBindingDepthT v+                                   guardMsg (depth == depth') "Specified binding depth does not match that of variable binding, this is probably a shadowing occurrence."+                e <- idR+                (rhs,_) <- getUnfoldingT AllBinders <<< return v+                maybe (fail "no match.") return (fold v rhs e)++------------------------------------------------------------------------++countBinders :: CoreExpr -> Int+countBinders e = length vs+    where (vs,_) = collectBinders e++collectNBinders :: Int -> CoreExpr -> Maybe ([Var], CoreExpr)+collectNBinders = go []+  where+    go bs 0 e         = return (reverse bs, e)+    go bs i (Lam b e) = go (b:bs) (i-1) e+    go _ _  _         = Nothing++-- return Nothing if not equal, so sequence will fail below+checkEqual :: Maybe CoreExpr -> Maybe CoreExpr -> Maybe CoreExpr+checkEqual m1 m2 = ifM (exprAlphaEq <$> m1 <*> m2) m1 Nothing++fold :: Id -> CoreExpr -> CoreExpr -> Maybe CoreExpr+fold i lam exp = do+    (vs,body) <- collectNBinders (countBinders lam - countBinders exp) lam+    al <- foldMatch vs [] body exp++    let m = Map.fromListWith checkEqual [(k,Just v) | (k,v) <- al ]++    es <- sequence [ join (Map.lookup v m) | v <- vs ]+    return $ mkCoreApps (varToCoreExpr i) es++-- Note: Id in the concrete instance is first+-- (not the Id found in the definition we are trying to fold).+addAlpha :: Id -> Id -> [(Id,Id)] -> [(Id,Id)]+addAlpha rId lId alphas | rId == lId = alphas+                        | otherwise  = (rId,lId) : alphas++-- Note: return list can have duplicate keys, caller is responsible+-- for checking that dupes refer to same expression+foldMatch :: [Var]          -- ^ vars that can unify with anything+          -> [(Id,Id)]      -- ^ alpha equivalences, wherever there is binding+                            --   note: we depend on behavior of lookup here, so new entries+                            --         should always be added to the front of the list so+                            --         we don't have to explicity remove them when shadowing occurs+          -> CoreExpr       -- ^ pattern we are matching on+          -> CoreExpr       -- ^ expression we are checking+          -> Maybe [(Var,CoreExpr)] -- ^ mapping of vars to expressions, or failure+foldMatch vs as (Var i) e | i `elem` vs = return [(i,e)]+                          | otherwise   = case e of+                                            Var i' | maybe False (==i) (lookup i' as) -> return [(i,e)]+                                                   | i == i' -> return []+                                            _                -> Nothing+foldMatch _  _ (Lit l) (Lit l') | l == l' = return []+foldMatch vs as (App e a) (App e' a') = do+    x <- foldMatch vs as e e'+    y <- foldMatch vs as a a'+    return (x ++ y)+foldMatch vs as (Lam v e) (Lam v' e') = foldMatch (filter (/=v) vs) (addAlpha v' v as) e e'+foldMatch vs as (Let (NonRec v rhs) e) (Let (NonRec v' rhs') e') = do+    x <- foldMatch vs as rhs rhs'+    y <- foldMatch (filter (/=v) vs) (addAlpha v' v as) e e'+    return (x ++ y)+-- TODO: this depends on bindings being in the same order+foldMatch vs as (Let (Rec bnds) e) (Let (Rec bnds') e') | length bnds == length bnds' = do+    let vs' = filter (`notElem` map fst bnds) vs+        as' = foldr (uncurry addAlpha) as $ zip (map fst bnds) (map fst bnds')+        bmatch (_,rhs) (_,rhs') = foldMatch vs' as' rhs rhs'+    x <- zipWithM bmatch bnds bnds'+    y <- foldMatch vs' as' e e'+    return (concat x ++ y)+foldMatch vs as (Tick t e) (Tick t' e') | t == t' = foldMatch vs as e e'+foldMatch vs as (Case s b ty alts) (Case s' b' ty' alts')+  | length alts == length alts' = do+    t <- foldMatch vs as (Type ty) (Type ty')+    x <- foldMatch vs as s s'+    let as' = addAlpha b' b as+        vs' = filter (/=b) vs+        altMatch (ac, is, e) (ac', is', e') | ac == ac' =+            foldMatch (filter (`notElem` is) vs') (foldr (uncurry addAlpha) as' $ zip is' is) e e'+        altMatch _ _ = Nothing+    y <- zipWithM altMatch alts alts'+    return (x ++ t ++ concat y)+foldMatch vs as (Cast e c)   (Cast e' c')  | coreEqCoercion c c' = foldMatch vs as e e'+-- don't try to alpha type variables for now+foldMatch vs _  (Type t@(TyVarTy v)) e@(Type t') | v `elem` vs = return [(v,e)]+                                                 | eqType t t' = return []+                                                 | otherwise   = Nothing+foldMatch _ _   (Type t)     (Type t')     | eqType t t' = return []+foldMatch _ _   (Coercion c) (Coercion c') | coreEqCoercion c c' = return []+foldMatch _ _ _ _ = Nothing
+ src/HERMIT/Dictionary/Function.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE FlexibleContexts, RankNTypes #-}+module HERMIT.Dictionary.Function+    ( externals+    , staticArgR+    , staticArgPosR+    , staticArgPredR+    , staticArgTypesR+    )+where++import Control.Arrow++import Data.List (nub, intercalate, intersect, partition, transpose)++import HERMIT.Context+import HERMIT.Core+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC++import HERMIT.Dictionary.Common++externals ::  [External]+externals =+    [ external "static-arg" (promoteDefR staticArgR :: RewriteH Core)+        [ "perform the static argument transformation on a recursive function." ]+    , external "static-arg-types" (promoteDefR staticArgTypesR :: RewriteH Core)+        [ "perform the static argument transformation on a recursive function, only transforming type arguments." ]+    , external "static-arg-pos" (promoteDefR . staticArgPosR :: [Int] -> RewriteH Core)+        [ "perform the static argument transformation on a recursive function, only transforming the arguments specified (by index)." ]+    ]++------------------------------------------------------------------------------------------------------++-- | Traditional Static Argument Transformation+staticArgR :: (ExtendPath c Crumb, AddBindings c) => Rewrite c HermitM CoreDef+staticArgR = staticArgPredR (return . map fst)++-- | Static Argument Transformation that only considers type arguments to be static.+staticArgTypesR :: (ExtendPath c Crumb, AddBindings c) => Rewrite c HermitM CoreDef+staticArgTypesR = staticArgPredR (return . map fst . filter (isTyVar . snd))++-- | Static Argument Transformations which requires that arguments in the given position are static.+staticArgPosR :: (ExtendPath c Crumb, AddBindings c) => [Int] -> Rewrite c HermitM CoreDef+staticArgPosR is' = staticArgPredR $ \ss' -> let is = nub is'+                                                 ss = map fst ss'+                                            in if is == (is `intersect` ss)+                                               then return is+                                               else fail $ "args " ++ commas (filter (`notElem` ss) is) ++ " are not static."++-- | Generalized Static Argument Transformation, which allows static arguments to be filtered.+staticArgPredR :: (ExtendPath c Crumb, AddBindings c)+               => ([(Int, Var)] -> HermitM [Int]) -- ^ given list of static args and positions, decided which to transform+               -> Rewrite c HermitM CoreDef+staticArgPredR decide = prefixFailMsg "static-arg failed: " $ do+    Def f rhs <- idR+    let (bnds, body) = collectBinders rhs+    guardMsg (notNull bnds) "rhs is not a function"+    contextonlyT $ \ c -> do+        let bodyContext = foldl (flip addLambdaBinding) c bnds++        callPats <- apply (callsT (var2THName f) (callT >>> arr snd)) bodyContext (ExprCore body)+        let argExprs = transpose callPats+            numCalls = length callPats+            allBinds = zip [0..] bnds++            staticBinds = [ (i,b) | ((i,b),exprs) <- zip allBinds $ argExprs ++ repeat []+                                  , length exprs == numCalls && isStatic b exprs ]+                                    -- ensure argument is present in every call (partial applications boo)++            isStatic _ []                          = True  -- all were static+            isStatic b ((Var b'):es)               | b == b' = isStatic b es+            isStatic b ((Type (TyVarTy v)):es)     | b == v  = isStatic b es+            isStatic b ((Coercion (CoVarCo v)):es) | b == v  = isStatic b es+            isStatic _ _                           = False -- not a simple repass, so dynamic++        chosen <- decide staticBinds+        let choices = map fst staticBinds+        guardMsg (notNull chosen) "no arguments selected for transformation."+        guardMsg (all (`elem` choices) chosen)+            $ "args " ++ commas choices ++ " are static, but " ++ commas chosen ++ " were selected."++        let (chosenBinds, dynBinds) = partition ((`elem` chosen) . fst) allBinds+            (ps, dbnds) = unzip dynBinds+            unboundTys = concat [ [ (i,i') | (i',b') <- dynBinds, i' < i , b' `elem` fvs ]+                                | (i,b) <- chosenBinds, let fvs = varSetElems (varTypeTyVars b) ]++        guardMsg (null unboundTys)+            $ "type variables in args " ++ commas (nub $ map fst unboundTys) ++ " would become unbound unless args "+              ++ commas (nub $ map snd unboundTys) ++ " are included in the transformation."++        wkr <- newIdH (var2String f ++ "'") (exprType (mkCoreLams dbnds body))++        let replaceCall :: Monad m => Rewrite c m CoreExpr+            replaceCall = do+                (_,exprs) <- callT+                return $ mkApps (Var wkr) [ e | (p,e) <- zip [0..] exprs, (p::Int) `elem` ps ]++        ExprCore body' <- apply (callsR (var2THName f) replaceCall) bodyContext (ExprCore body)++        return $ Def f $ mkCoreLams bnds $ Let (Rec [(wkr, mkCoreLams dbnds body')])+                                             $ mkApps (Var wkr) (varsToCoreExprs dbnds)++commas :: Show a => [a] -> String+commas = intercalate "," . map show
+ src/HERMIT/Dictionary/GHC.hs view
@@ -0,0 +1,375 @@+{-# LANGUAGE CPP, FlexibleContexts, ScopedTypeVariables #-}+module HERMIT.Dictionary.GHC+       ( -- * GHC-based Transformations+         -- | This module contains transformations that are reflections of GHC functions, or derived from GHC functions.+         externals+       , anyCallR+         -- ** Substitution+       , substR+       , substExprR+         -- ** Utilities+       , inScope+       , rule+       , rules+       , dynFlagsT+       , arityOf+         -- ** Lifted GHC capabilities+         -- A zombie is an identifer that has 'OccInfo' 'IAmDead', but still has occurrences.+       , lintExprT+       , lintModuleT+       , specConstrR+       , occurAnalyseR+       , occurAnalyseChangedR+       , occurAnalyseExprChangedR+       , occurAnalyseAndDezombifyR+       , dezombifyR+       )+where++import qualified Bag+import qualified CoreLint+import IOEnv hiding (liftIO)+import qualified SpecConstr++import Control.Arrow+import Control.Monad++import Data.Function (on)+import Data.List (mapAccumL,deleteFirstsBy)++import HERMIT.Core+import HERMIT.Context+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC++import HERMIT.Dictionary.Debug hiding (externals)++import qualified Language.Haskell.TH as TH++------------------------------------------------------------------------++-- | Externals that reflect GHC functions, or are derived from GHC functions.+externals :: [External]+externals =+         [ external "deshadow-prog" (promoteProgR deShadowProgR :: RewriteH Core)+                [ "Deshadow a program." ] .+ Deep+         , external "apply-rule" (promoteExprR . rule :: String -> RewriteH Core)+                [ "Apply a named GHC rule" ] .+ Shallow+         , external "apply-rule" (rules_help :: TranslateH Core String)+                [ "List rules that can be used" ] .+ Query+         , external "apply-rules" (promoteExprR . rules :: [String] -> RewriteH Core)+                [ "Apply named GHC rules, succeed if any of the rules succeed" ] .+ Shallow+         , external "add-rule" ((\ rule_name id_name -> promoteModGutsR (addCoreBindAsRule rule_name id_name)) :: String -> TH.Name -> RewriteH Core)+                [ "add-rule \"rule-name\" <id> -- adds a new rule that freezes the right hand side of the <id>"]  .+ Introduce+         , external "dezombify" (promoteExprR dezombifyR :: RewriteH Core)+                [ "Zap the occurrence information in the current identifer if it is a zombie."] .+ Shallow+         , external "occurrence-analysis" (occurrenceAnalysisR :: RewriteH Core)+                [ "Perform dependency analysis on all sub-expressions; simplifying and updating identifer info."] .+ Deep+         , external "lint-expr" (promoteExprT lintExprT :: TranslateH Core String)+                [ "Runs GHC's Core Lint, which typechecks the current expression."+                , "Note: this can miss several things that a whole-module core lint will find."+                , "For instance, running this on the RHS of a binding, the type of the RHS will"+                , "not be checked against the type of the binding. Running on the whole let expression"+                , "will catch that however."] .+ Deep .+ Debug .+ Query+         , external "lint-module" (promoteModGutsT lintModuleT :: TranslateH Core String)+                [ "Runs GHC's Core Lint, which typechecks the current module."] .+ Deep .+ Debug .+ Query+         , external "spec-constr" (promoteModGutsR specConstrR :: RewriteH Core)+                [ "Run GHC's SpecConstr pass, which performs call pattern specialization."] .+ Deep+         , external "any-call" (anyCallR :: RewriteH Core -> RewriteH Core)+                [ "any-call (.. unfold command ..) applies an unfold command to all applications."+                , "Preference is given to applications with more arguments." ] .+ Deep+         ]++------------------------------------------------------------------------++-- | Substitute all occurrences of a variable with an expression, in either a program or an expression.+substR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Var -> CoreExpr -> Rewrite c m Core+substR v e = setFailMsg "Can only perform substitution on expressions or programs." $+             promoteExprR (substExprR v e) <+ promoteProgR (substTopBindR v e) <+ promoteAltR (substAltR v e)++-- | Substitute all occurrences of a variable with an expression, in an expression.+substExprR :: Monad m => Var -> CoreExpr -> Rewrite c m CoreExpr+substExprR v e =  contextfreeT $ \ expr -> do+    -- The InScopeSet needs to include any free variables appearing in the+    -- expression to be substituted.  Constructing a NonRec Let expression+    -- to pass on to exprFeeVars takes care of this, but ...+    -- TODO Is there a better way to do this ???+    let emptySub = mkEmptySubst (mkInScopeSet (localFreeVarsExpr (Let (NonRec v e) expr)))+    return $ substExpr (text "substR") (extendSubst emptySub v e) expr++-- | Substitute all occurrences of a variable with an expression, in a program.+substTopBindR :: Monad m => Var -> CoreExpr -> Rewrite c m CoreProg+substTopBindR v e =  contextfreeT $ \ p -> do+    -- TODO.  Do we need to initialize the emptySubst with bindFreeVars?+    let emptySub =  emptySubst -- mkEmptySubst (mkInScopeSet (exprFreeVars exp))+    return $ bindsToProg $ snd (mapAccumL substBind (extendSubst emptySub v e) (progToBinds p))++-- | Substitute all occurrences of a variable with an expression, in a case alternative.+substAltR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Var -> CoreExpr -> Rewrite c m CoreAlt+substAltR v e = do (_, vs, _) <- idR+                   if v `elem` vs+                    then fail "variable is shadowed by a case-alternative constructor argument."+                    else altAllR idR (\ _ -> idR) (substExprR v e)++-- Neil: Commented this out as it's not (currently) used.+--  Perform let-substitution the specified number of times.+-- letSubstNR :: Int -> Rewrite c m Core+-- letSubstNR 0 = idR+-- letSubstNR n = childR 1 (letSubstNR (n - 1)) >>> promoteExprR letSubstR++------------------------------------------------------------------------++-- | [from GHC documentation] De-shadowing the program is sometimes a useful pre-pass.+-- It can be done simply by running over the bindings with an empty substitution,+-- becuase substitution returns a result that has no-shadowing guaranteed.+--+-- (Actually, within a single /type/ there might still be shadowing, because+-- 'substTy' is a no-op for the empty substitution, but that's probably OK.)+deShadowProgR :: Monad m => Rewrite c m CoreProg+deShadowProgR = arr (bindsToProg . deShadowBinds . progToBinds)++------------------------------------------------------------------------+{-+lookupRule :: (Activation -> Bool)	-- When rule is active+	    -> IdUnfoldingFun		-- When Id can be unfolded+            -> InScopeSet+	    -> Id -> [CoreExpr]+	    -> [CoreRule] -> Maybe (CoreRule, CoreExpr)++GHC HEAD:+type InScopeEnv = (InScopeSet, IdUnfoldingFun)++lookupRule :: DynFlags -> InScopeEnv+           -> (Activation -> Bool)      -- When rule is active+           -> Id -> [CoreExpr]+           -> [CoreRule] -> Maybe (CoreRule, CoreExpr)+-}++-- Neil: Commented this out as its not (currently) used.+-- rulesToEnv :: [CoreRule] -> Map.Map String (Rewrite c m CoreExpr)+-- rulesToEnv rs = Map.fromList+--         [ ( unpackFS (ruleName r), rulesToRewrite c m [r] )+--         | r <- rs+--         ]++#if __GLASGOW_HASKELL__ > 706+rulesToRewriteH :: (ReadBindings c, HasDynFlags m, MonadCatch m) => [CoreRule] -> Rewrite c m CoreExpr+#else+rulesToRewriteH :: (ReadBindings c, MonadCatch m) => [CoreRule] -> Rewrite c m CoreExpr+#endif+rulesToRewriteH rs = prefixFailMsg "RulesToRewrite failed: " $+                     withPatFailMsg "rule not matched." $+                     translate $ \ c e -> do+    -- First, we normalize the lhs, so we can match it+    (Var fn,args) <- return $ collectArgs e+    -- Question: does this include Id's, or Var's (which include type names)+    -- Assumption: Var's.+    let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- varSetElems (localFreeVarsExpr e) ])+        -- The rough_args are just an attempt to try eliminate silly things+        -- that will never match+        _rough_args = map (const Nothing) args   -- rough_args are never used!!! FIX ME!+    -- Finally, we try match the rules+    -- trace (showSDoc (ppr fn <+> ppr args $$ ppr rs)) $+#if __GLASGOW_HASKELL__ > 706+    dflags <- getDynFlags+    case lookupRule dflags (in_scope, const NoUnfolding) (const True) fn args [r | r <- rs, ru_fn r == idName fn] of+#else+    case lookupRule (const True) (const NoUnfolding) in_scope fn args [r | r <- rs, ru_fn r == idName fn] of+#endif+        Nothing         -> fail "rule not matched"+        Just (r, expr)  -> do+            let e' = mkApps expr (drop (ruleArity r) args)+            if all (inScope c) $ varSetElems $ localFreeVarsExpr e' -- TODO: The problem with this check, is that it precludes the case where this is an intermediate transformation.  I can imagine situations where some variables would be out-of-scope at this point, but in scope again after a subsequent transformation.+              then return e'+              else fail $ unlines ["Resulting expression after rule application contains variables that are not in scope."+                                  ,"This can probably be solved by running the flatten-module command at the top level."]++-- | Determine whether an identifier is in scope.+inScope :: ReadBindings c => c -> Id -> Bool+inScope c v = (v `boundIn` c) ||                 -- defined in this module+              case unfoldingInfo (idInfo v) of+                CoreUnfolding {} -> True         -- defined elsewhere+                DFunUnfolding {} -> True+                _                -> False++-- | Lookup a rule and attempt to construct a corresponding rewrite.+rule :: (ReadBindings c, HasCoreRules c) => String -> Rewrite c HermitM CoreExpr+rule r = do+    theRules <- getHermitRules+    case lookup r theRules of+        Nothing -> fail $ "failed to find rule: " ++ show r+        Just rr -> rulesToRewriteH rr++rules :: (ReadBindings c, HasCoreRules c) => [String] -> Rewrite c HermitM CoreExpr+rules = orR . map rule++getHermitRules :: HasCoreRules c => Translate c HermitM a [(String, [CoreRule])]+getHermitRules = contextonlyT $ \ c -> do+    rb     <- liftCoreM getRuleBase+    hscEnv <- liftCoreM getHscEnv+    rb'    <- liftM eps_rule_base $ liftIO $ runIOEnv () $ readMutVar (hsc_EPS hscEnv)+    return [ ( unpackFS (ruleName r), [r] )+           | r <- hermitCoreRules c ++ concat (nameEnvElts rb) ++ concat (nameEnvElts rb')+           ]++rules_help :: HasCoreRules c => Translate c HermitM Core String+rules_help = do+    rulesEnv <- getHermitRules+    dynFlags <- dynFlagsT+    return  $ (show (map fst rulesEnv) ++ "\n") +++              showSDoc dynFlags (pprRulesForUser $ concatMap snd rulesEnv)++makeRule :: String -> Id -> CoreExpr -> CoreRule+makeRule rule_name nm =   mkRule True   -- auto-generated+                                 False  -- local+                                 (mkFastString rule_name)+                                 NeverActive    -- because we need to call for these+                                 (varName nm)+                                 []+                                 []++-- TODO: check if a top-level binding+addCoreBindAsRule :: Monad m => String -> TH.Name -> Rewrite c m ModGuts+addCoreBindAsRule rule_name nm = contextfreeT $ \ modGuts ->+        case [ (v,e)+             | bnd   <- mg_binds modGuts+             , (v,e) <- bindToVarExprs bnd+             ,  nm `cmpTHName2Var` v+             ] of+         [] -> fail $ "cannot find binding " ++ show nm+         [(v,e)] -> return $ modGuts { mg_rules = mg_rules modGuts+                                              ++ [makeRule rule_name v e]+                                     }+         _ -> fail $ "found multiple bindings for " ++ show nm++--------------------------------------------------------++-- | Try to figure out the arity of an identifier.+arityOf :: ReadBindings c => c -> Id -> Int+arityOf c i =+     case lookupHermitBinding i c of+        Nothing       -> idArity i+        -- Note: the exprArity will call idArity if+        -- it hits an id; perhaps we should do the counting+        -- The advantage of idArity is it will terminate, though.+        Just b -> runKureM exprArity+                           (const 0) -- conservative estimate, as we don't know what the expression looks like+                           (hermitBindingExpr b)++-------------------------------------------++-- | Run the Core Lint typechecker.+-- Fails on errors, with error messages.+-- Succeeds returning warnings.+lintModuleT :: TranslateH ModGuts String+lintModuleT =+  do dynFlags <- dynFlagsT+     bnds     <- arr mg_binds+#if __GLASGOW_HASKELL__ > 706+     let (warns, errs)    = CoreLint.lintCoreBindings [] bnds -- [] are vars to treat as in scope, used by GHCi+#else+     let (warns, errs)    = CoreLint.lintCoreBindings bnds+#endif+         dumpSDocs endMsg = Bag.foldBag (\ d r -> d ++ ('\n':r)) (showSDoc dynFlags) endMsg+     if Bag.isEmptyBag errs+       then return $ dumpSDocs "Core Lint Passed" warns+       else observeR (dumpSDocs "" errs) >>> fail "Core Lint Failed"++-- | Note: this can miss several things that a whole-module core lint will find.+-- For instance, running this on the RHS of a binding, the type of the RHS will+-- not be checked against the type of the binding. Running on the whole let expression+-- will catch that however.+lintExprT :: (BoundVars c, Monad m, HasDynFlags m) => Translate c m CoreExpr String+lintExprT = translate $ \ c e -> do+    dflags <- getDynFlags+    maybe (return "Core Lint Passed") (fail . showSDoc dflags)+#if __GLASGOW_HASKELL__ > 706+                 $ CoreLint.lintExpr (varSetElems $ boundVars c) e+#else+                 $ CoreLint.lintUnfolding noSrcLoc (varSetElems $ boundVars c) e+#endif++specConstrR :: RewriteH ModGuts+specConstrR = do+    rs  <- extractT specRules+    e'  <- contextfreeT $ liftCoreM . SpecConstr.specConstrProgram+    rs' <- return e' >>> extractT specRules+    let specRs = deleteFirstsBy ((==) `on` ru_name) rs' rs+    return e' >>> extractR (repeatR (anyCallR (promoteExprR $ rulesToRewriteH specRs)))++-- | Get all the specialization rules on a binding.+--   These are created by SpecConstr and other GHC passes.+idSpecRules :: TranslateH Id [CoreRule]+idSpecRules = contextfreeT $ \ i -> let SpecInfo rs _ = specInfo (idInfo i) in return rs++-- | Promote 'idSpecRules' to CoreBind.+bindSpecRules :: TranslateH CoreBind [CoreRule]+bindSpecRules =    recT (\_ -> defT idSpecRules (return ()) const) concat+                <+ nonRecT idSpecRules (return ()) const++-- | Find all specialization rules in a Core fragment.+specRules :: TranslateH Core [CoreRule]+specRules = crushtdT $ promoteBindT bindSpecRules++-- | Top-down traversal tuned to matching function calls.+anyCallR :: forall c m. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m)+         => Rewrite c m Core -> Rewrite c m Core+anyCallR rr = prefixFailMsg "any-call failed: " $+              readerT $ \ e -> case e of+        ExprCore (App {}) -> childR App_Arg rec >+> (rr <+ childR App_Fun rec)+        ExprCore (Var {}) -> rr+        _                 -> anyR rec+    where rec :: Rewrite c m Core+          rec = anyCallR rr++-------------------------------------------++-- | Lifted version of 'getDynFlags'.+dynFlagsT :: HasDynFlags m => Translate c m a DynFlags+dynFlagsT = constT getDynFlags++-------------------------------------------++----------------------------------------------------------------------++-- TODO: Ideally, occurAnalyseExprR would fail if nothing changed.+--       This is tricky though, as it's not just the structure of the expression, but also the meta-data.++-- | Zap the 'OccInfo' in a zombie identifier.+dezombifyR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr+dezombifyR = varR (acceptR isDeadBinder >>^ zapVarOccInfo)++-- | Apply 'occurAnalyseExprR' to all sub-expressions.+occurAnalyseR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core+occurAnalyseR = let r  = promoteExprR (arr occurAnalyseExpr)+                    go = r <+ anyR go+                 in tryR go -- always succeed++-- | Occurrence analyse an expression, failing if the result is syntactically equal to the initial expression.+occurAnalyseExprChangedR :: MonadCatch m => Rewrite c m CoreExpr+occurAnalyseExprChangedR = changedByR exprSyntaxEq (arr occurAnalyseExpr)++-- | Occurrence analyse all sub-expressions, failing if the result is syntactically equal to the initial expression.+occurAnalyseChangedR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core+occurAnalyseChangedR = changedByR coreSyntaxEq occurAnalyseR++-- | Run GHC's occurrence analyser, and also eliminate any zombies.+occurAnalyseAndDezombifyR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core+occurAnalyseAndDezombifyR = allbuR (tryR $ promoteExprR dezombifyR) >>> occurAnalyseR++occurrenceAnalysisR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m Core+occurrenceAnalysisR = occurAnalyseAndDezombifyR++{- Does not work (no export)+-- Here is a hook into the occur analysis, and a way of looking at the result+occAnalysis ::  CoreExpr -> UsageDetails+occAnalysis = fst . occAnal (initOccEnv all_active_rules)++lookupUsageDetails :: UsageDetails -> Var -> Maybe OccInfo+lookupUsageDetails = lookupVarEnv++-}++----------------------------------------------------------------------
+ src/HERMIT/Dictionary/Inline.hs view
@@ -0,0 +1,217 @@+{-# LANGUAGE CPP, TupleSections, FlexibleContexts, ScopedTypeVariables #-}+module HERMIT.Dictionary.Inline+         ( -- * Inlining+           externals+         , InlineConfig(..)+         , CaseBinderInlineOption(..)+         , getUnfoldingT+         , inlineR+         , inlineNameR+         , inlineNamesR+         , inlineCaseScrutineeR+         , inlineCaseAlternativeR+         , configurableInlineR+         , inlineTargetsT+         )++where++#if __GLASGOW_HASKELL__ > 706+#else+import TcType (tcSplitDFunTy)+#endif++import Control.Arrow+import Control.Applicative+import Control.Monad++import HERMIT.Context+import HERMIT.Core+import HERMIT.External+import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad++import HERMIT.Dictionary.Common++import qualified Language.Haskell.TH as TH++------------------------------------------------------------------------++-- | 'External's for inlining variables.+externals :: [External]+externals =+            [ external "inline" (promoteExprR inlineR :: RewriteH Core)+                [ "(Var v) ==> <defn of v>" ].+ Eval .+ Deep+            , external "inline" (promoteExprR . inlineNameR :: TH.Name -> RewriteH Core)+                [ "Given a specific v, (Var v) ==> <defn of v>" ] .+ Eval .+ Deep+            , external "inline" (promoteExprR . inlineNamesR :: [TH.Name] -> RewriteH Core)+                [ "If the current variable matches any of the given names, then inline it." ] .+ Eval .+ Deep+            , external "inline-case-scrutinee" (promoteExprR inlineCaseScrutineeR :: RewriteH Core)+                [ "if v is a case binder, replace (Var v) with the bound case scrutinee." ] .+ Eval .+ Deep+            , external "inline-case-alternative" (promoteExprR inlineCaseAlternativeR :: RewriteH Core)+                [ "if v is a case binder, replace (Var v) with the bound case-alternative pattern." ] .+ Eval .+ Deep .+ Unsafe+            ]++------------------------------------------------------------------------++-- extend these data types as needed if other inlining behaviour becomes desireable+data CaseBinderInlineOption = Scrutinee | Alternative deriving (Eq, Show)+data InlineConfig           = CaseBinderOnly CaseBinderInlineOption | AllBinders deriving (Eq, Show)++-- | If the current variable matches the given name, then inline it.+inlineNameR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM CoreExpr+inlineNameR nm = configurableInlineR AllBinders (arr $ cmpTHName2Var nm)++-- | If the current variable matches any of the given names, then inline it.+inlineNamesR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [TH.Name] -> Rewrite c HermitM CoreExpr+inlineNamesR []  = fail "inline-names failed: no names given."+inlineNamesR nms = configurableInlineR AllBinders (arr $ \ v -> any (flip cmpTHName2Var v) nms)++-- | Inline the current variable.+inlineR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+inlineR = configurableInlineR AllBinders (return True)++-- | Inline the current identifier if it is a case binder, using the scrutinee rather than the case-alternative pattern.+inlineCaseScrutineeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+inlineCaseScrutineeR = configurableInlineR (CaseBinderOnly Scrutinee) (return True)++-- | Inline the current identifier if is a case binder, using the case-alternative pattern rather than the scrutinee.+inlineCaseAlternativeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+inlineCaseAlternativeR = configurableInlineR (CaseBinderOnly Alternative) (return True)++-- | The implementation of inline, an important transformation.+-- This *only* works if the current expression has the form @Var v@ (it does not traverse the expression).+-- It can trivially be prompted to more general cases using traversal strategies.+configurableInlineR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c)+                    => InlineConfig+                    -> (Translate c HermitM Id Bool) -- ^ Only inline identifiers that satisfy this predicate.+                    -> Rewrite c HermitM CoreExpr+configurableInlineR config p =+   prefixFailMsg "Inline failed: " $+   do b <- varT p+      guardMsg b "identifier does not satisfy predicate."+      (e,uncaptured) <- varT (getUnfoldingT config)+      setFailMsg "values in inlined expression have been rebound."+        (return e >>> accepterR (ensureDepthT uncaptured))+++-- NOTE: When inlining, we have to take care to avoid variable capture.+--       Our approach is to track the binding depth of the inlined identifier.+--       After inlining, we then resolve all names in the inlined expression, and require that they were all bound prior to (i.e. lower numbered depth) the binding we inlined.+--       The precise depth check varies between binding types as follows (where d is the depth of the inlined binder):+--+--         Binder                Safe to Inline+--         global-id             (<= 0)+--         letnonrec             (< d)+--         letrec                (<= d)+--         case-wild-scrutinee   (< d)+--         case-wild-alt         (<= d+1)+--         self-rec-def          NA+--         lam                   NA+--         case-alt              NA+++-- | Ensure all the free variables in an expression were bound above a given depth.+-- Assumes minimum depth is 0.+ensureDepthT :: forall c m. (ExtendPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m) => (BindingDepth -> Bool) -> Translate c m CoreExpr Bool+ensureDepthT uncaptured =+  do frees <- arr localFreeVarsExpr+     let collectDepthsT :: Translate c m Core [BindingDepth]+         collectDepthsT = collectT $ promoteExprT $ varT (acceptR (`elemVarSet` frees) >>> readerT varBindingDepthT)+     all uncaptured `liftM` extractT collectDepthsT++-- | Return the unfolding of an identifier, and a predicate over the binding depths of all variables within that unfolding to determine if they have been captured in their new location.+getUnfoldingT :: ReadBindings c+              => InlineConfig+              -> Translate c HermitM Id (CoreExpr, BindingDepth -> Bool)+getUnfoldingT config = translate $ \ c i ->+    case lookupHermitBinding i c of+      Nothing -> do requireAllBinders config+                    let uncaptured = (<= 0) -- i.e. is global+                    case unfoldingInfo (idInfo i) of+                      CoreUnfolding { uf_tmpl = uft } -> return (uft, uncaptured)+#if __GLASGOW_HASKELL__ > 706+                      dunf@(DFunUnfolding {})         -> (,uncaptured) <$> dFunExpr dunf+#else+                      DFunUnfolding _arity dc args    -> (,uncaptured) <$> dFunExpr dc args (idType i)+#endif+                      _                               -> fail $ "cannot find unfolding in Env or IdInfo."+      Just (depth,b) -> case b of+                          CASEWILD s alt -> let tys             = tyConAppArgs (idType i)+                                                altExprDepthM   = (, (<= depth+1)) <$> alt2Exp tys alt+                                                scrutExprDepthM = return (s, (< depth))+                                             in case config of+                                                  CaseBinderOnly Scrutinee   -> scrutExprDepthM+                                                  CaseBinderOnly Alternative -> altExprDepthM+                                                  AllBinders                 -> altExprDepthM <+ scrutExprDepthM++                          NONREC e       -> do requireAllBinders config+                                               return (e, (< depth))++                          REC e          -> do requireAllBinders config+                                               return (e, (<= depth))++                          _              -> fail "variable is not bound to an expression."+  where+    requireAllBinders :: Monad m => InlineConfig -> m ()+    requireAllBinders AllBinders         = return ()+    requireAllBinders (CaseBinderOnly _) = fail "not a case binder."++-- | Convert lhs of case alternative to a constructor application expression,+--   failing in the case of the DEFAULT alternative.+--   Accepts a list of types to apply to the constructor before the value args.+--+-- > data T a b = C a b Int+--+-- Pseudocode:+--+-- > alt2Exp (...) [a,b] (C, [x,y,z]) ==> C a b (x::a) (y::b) (z::Int)+--+alt2Exp :: Monad m => [Type] -> (AltCon,[Var]) -> m CoreExpr+alt2Exp _   (DEFAULT   , _ ) = fail "DEFAULT alternative cannot be converted to an expression."+alt2Exp _   (LitAlt l  , _ ) = return $ Lit l+alt2Exp tys (DataAlt dc, vs) = return $ mkCoreConApps dc (map Type tys ++ map (varToCoreExpr . zapVarOccInfo) vs)++-- | Get list of possible inline targets. Used by shell for completion.+inlineTargetsT :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Translate c HermitM Core [String]+inlineTargetsT = collectT $ promoteT $ whenM (testM inlineR) (varT $ arr var2String)++-- | Build a CoreExpr for a DFunUnfolding+#if __GLASGOW_HASKELL__ > 706+{-+data Unfolding+  = ...+  | DFunUnfolding {     -- The Unfolding of a DFunId+                -- See Note [DFun unfoldings]+                --     df = /\a1..am. \d1..dn. MkD t1 .. tk+                        --                                 (op1 a1..am d1..dn)+                    --                                 (op2 a1..am d1..dn)+        df_bndrs :: [Var],      -- The bound variables [a1..m],[d1..dn]+        df_con   :: DataCon,    -- The dictionary data constructor (never a newtype datacon)+        df_args  :: [CoreExpr]  -- Args of the data con: types, superclasses and methods,+    }                           -- in positional order+-}+dFunExpr :: Unfolding -> HermitM CoreExpr+-- TODO: is this correct?+dFunExpr dunf@(DFunUnfolding {}) = return $ trace "dFunExpr" $ mkCoreConApps (df_con dunf) (df_args dunf)+dFunExpr _ = fail "dFunExpr: not a DFunUnfolding"+#else+dFunExpr :: DataCon -> [DFunArg CoreExpr] -> Type -> HermitM CoreExpr+dFunExpr dc args ty = do+    let (_, _, _, tcArgs) = tcSplitDFunTy ty+        (forallTvs, ty')  = splitForAllTys ty+        (argTys, _resTy)  = splitFunTys ty'++    ids <- mapM (uncurry newIdH) $ zip [ [ch] | ch <- cycle ['a'..'z'] ] argTys+    vars <- mapM (cloneVarH id) forallTvs++    let allVars = varsToCoreExprs $ vars ++ ids++        mkArg (DFunLamArg i) = allVars !! i+        mkArg (DFunPolyArg e) = mkCoreApps e allVars++    return $ mkCoreConApps dc $ map Type tcArgs ++ map mkArg args+#endif++------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Kure.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE FlexibleContexts #-}++module HERMIT.Dictionary.Kure+       ( -- * KURE Strategies+         externals+       )+where++import Control.Arrow+import Control.Monad (liftM)++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure+import HERMIT.External++------------------------------------------------------------------------------------++-- | -- This list contains reflections of the KURE strategies as 'External's.+externals :: [External]+externals = map (.+ KURE)+   [ external "id"         (idR :: RewriteH Core)+       [ "Perform an identity rewrite."] .+ Shallow+   , external "fail"       (fail :: String -> RewriteH Core)+       [ "A failing rewrite."]+   , external "<+"         ((<+) :: RewriteH Core -> RewriteH Core -> RewriteH Core)+       [ "Perform the first rewrite, and then, if it fails, perform the second rewrite." ]+   , external "<+"         ((<+) :: TranslateH Core () -> TranslateH Core () -> TranslateH Core ())+       [ "Perform the first check, and then, if it fails, perform the second check." ]+   , external ">>>"        ((>>>) :: RewriteH Core -> RewriteH Core -> RewriteH Core)+       [ "Compose rewrites, requiring both to succeed." ]+   , external ">>>"        ((>>>) :: BiRewriteH Core -> BiRewriteH Core -> BiRewriteH Core)+       [ "Compose bidirectional rewrites, requiring both to succeed." ]+   , external ">+>"        ((>+>) :: RewriteH Core -> RewriteH Core -> RewriteH Core)+       [ "Compose rewrites, allowing one to fail." ]+   , external "try"        (tryR :: RewriteH Core -> RewriteH Core)+       [ "Try a rewrite, and perform the identity if the rewrite fails." ]+   , external "repeat"     (repeatR :: RewriteH Core -> RewriteH Core)+       [ "Repeat a rewrite until it would fail." ] .+ Loop+   , external "replicate"  ((\ n -> andR . replicate n)  :: Int -> RewriteH Core -> RewriteH Core)+       [ "Repeat a rewrite n times." ]+   , external "all"        (allR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to all children of the node, requiring success at every child." ] .+ Shallow+   , external "any"        (anyR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to all children of the node, requiring success for at least one child." ] .+ Shallow+   , external "one"        (oneR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to the first child of the node for which it can succeed." ] .+ Shallow+   , external "all-bu"     (allbuR :: RewriteH Core -> RewriteH Core)+       [ "Promote a rewrite to operate over an entire tree in bottom-up order, requiring success at every node." ] .+ Deep+   , external "all-td"     (alltdR :: RewriteH Core -> RewriteH Core)+       [ "Promote a rewrite to operate over an entire tree in top-down order, requiring success at every node." ] .+ Deep+   , external "all-du"     (allduR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite twice, in a top-down and bottom-up way, using one single tree traversal,",+         "succeeding if they all succeed."] .+ Deep+   , external "any-bu"     (anybuR :: RewriteH Core -> RewriteH Core)+       [ "Promote a rewrite to operate over an entire tree in bottom-up order, requiring success for at least one node." ] .+ Deep+   , external "any-td"     (anytdR :: RewriteH Core -> RewriteH Core)+       [ "Promote a rewrite to operate over an entire tree in top-down order, requiring success for at least one node." ] .+ Deep+   , external "any-du"     (anyduR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite twice, in a top-down and bottom-up way, using one single tree traversal,",+         "succeeding if any succeed."] .+ Deep+   , external "one-td"     (onetdR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to the first node (in a top-down order) for which it can succeed." ] .+ Deep+   , external "one-bu"     (onebuR :: RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to the first node (in a bottom-up order) for which it can succeed." ] .+ Deep+   , external "prune-td"   (prunetdR :: RewriteH Core -> RewriteH Core)+       [ "Attempt to apply a rewrite in a top-down manner, prunning at successful rewrites." ] .+ Deep+   , external "innermost"  (innermostR :: RewriteH Core -> RewriteH Core)+       [ "A fixed-point traveral, starting with the innermost term." ] .+ Deep .+ Loop+   , external "focus"      (hfocusR :: TranslateH Core LocalPathH -> RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to a focal point."] .+ Navigation .+ Deep+   , external "focus"      (hfocusT :: TranslateH Core LocalPathH -> TranslateH Core String -> TranslateH Core String)+       [ "Apply a query at a focal point."] .+ Navigation .+ Deep+   , external "focus"      (hfocusR . return :: LocalPathH -> RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite to a focal point."] .+ Navigation .+ Deep+   , external "focus"      (hfocusT . return :: LocalPathH -> TranslateH Core String -> TranslateH Core String)+       [ "Apply a query at a focal point."] .+ Navigation .+ Deep+   , external "when"       ((>>) :: TranslateH Core () -> RewriteH Core -> RewriteH Core)+       [ "Apply a rewrite only if the check succeeds." ] .+ Predicate+   , external "not"        (notM :: TranslateH Core () -> TranslateH Core ())+       [ "Cause a failing check to succeed, a succeeding check to fail." ] .+ Predicate+   , external "invert"     (invertBiT :: BiRewriteH Core -> BiRewriteH Core)+       [ "Reverse a bidirectional rewrite." ]+   , external "forward"    (forwardT :: BiRewriteH Core -> RewriteH Core)+       [ "Apply a bidirectional rewrite forewards." ]+   , external "backward"   (backwardT :: BiRewriteH Core -> RewriteH Core)+       [ "Apply a bidirectional rewrite backwards." ]+   , external "test"       (testQuery :: RewriteH Core -> TranslateH Core String)+       [ "Determine if a rewrite could be successfully applied." ]+   ]++------------------------------------------------------------------------------------++hfocusR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Core LocalPathH -> Rewrite c m Core -> Rewrite c m Core+hfocusR tp r = do lp <- tp+                  localPathR lp r+{-# INLINE hfocusR #-}++hfocusT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Core LocalPathH -> Translate c m Core String -> Translate c m Core String+hfocusT tp t = do lp <- tp+                  localPathT lp t+{-# INLINE hfocusT #-}++------------------------------------------------------------------------------------++-- | Test if a rewrite would succeed, producing a string describing the result.+testQuery :: MonadCatch m => Rewrite c m g -> Translate c m g String+testQuery r = f `liftM` testM r+  where+    f :: Bool -> String+    f True  = "Rewrite would succeed."+    f False = "Rewrite would fail."+{-# INLINE testQuery #-}++------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Local.hs view
@@ -0,0 +1,235 @@+{-# LANGUAGE FlexibleContexts #-}++module HERMIT.Dictionary.Local+       ( -- * Local Structural Manipulations+         HERMIT.Dictionary.Local.externals+         -- ** Binding Groups+       , module HERMIT.Dictionary.Local.Bind+         -- ** Case Expressions+       , module HERMIT.Dictionary.Local.Case+         -- ** Cast Expressions+       , module HERMIT.Dictionary.Local.Cast+         -- ** Let Expressions+       , module HERMIT.Dictionary.Local.Let+         -- ** Miscellaneous+       , abstractR+       , pushR+       , betaReduceR+       , betaReducePlusR+       , betaExpandR+       , etaReduceR+       , etaExpandR+       , multiEtaExpandR+       , flattenModuleR+       , flattenProgramR+       , flattenProgramT+       )+where++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.External+import HERMIT.GHC+import HERMIT.Utilities++import HERMIT.Dictionary.Common+import HERMIT.Dictionary.Local.Bind hiding (externals)+import qualified HERMIT.Dictionary.Local.Bind as Bind+import HERMIT.Dictionary.Local.Case hiding (externals)+import qualified HERMIT.Dictionary.Local.Case as Case+import HERMIT.Dictionary.Local.Cast hiding (externals)+import qualified HERMIT.Dictionary.Local.Cast as Cast+import HERMIT.Dictionary.Local.Let hiding (externals)+import qualified HERMIT.Dictionary.Local.Let as Let++import qualified Language.Haskell.TH as TH++import Control.Arrow++------------------------------------------------------------------------------++-- | Externals for local structural manipulations.+--   (Many taken from Chapter 3 of Andre Santos' dissertation.)+externals :: [External]+externals =+    [ external "beta-reduce" (promoteExprR betaReduceR :: RewriteH Core)+        [ "((\\ v -> E1) E2) ==> let v = E2 in E1"+        , "This form of beta-reduction is safe if E2 is an arbitrary expression"+        , "(won't duplicate work)." ]                                 .+ Eval .+ Shallow+    , external "beta-reduce-plus" (promoteExprR betaReducePlusR :: RewriteH Core)+        [ "Perform one or more beta-reductions."]                               .+ Eval .+ Shallow+    , external "beta-expand" (promoteExprR betaExpandR :: RewriteH Core)+        [ "(let v = e1 in e2) ==> (\\ v -> e2) e1" ]                            .+ Shallow+    , external "eta-reduce" (promoteExprR etaReduceR :: RewriteH Core)+        [ "(\\ v -> e1 v) ==> e1" ]                                             .+ Eval .+ Shallow+    , external "eta-expand" (promoteExprR . etaExpandR . show :: TH.Name -> RewriteH Core)+        [ "\"eta-expand 'v\" performs e1 ==> (\\ v -> e1 v)" ]                  .+ Shallow .+ Introduce+    , external "flatten-module" (promoteModGutsR flattenModuleR :: RewriteH Core)+        [ "Flatten all the top-level binding groups in the module to a single recursive binding group."+        , "This can be useful if you intend to appply GHC RULES." ]+    , external "flatten-program" (promoteProgR flattenProgramR :: RewriteH Core)+        [ "Flatten all the top-level binding groups in a program (list of binding groups) to a single"+        , "recursive binding group.  This can be useful if you intend to apply GHC RULES." ]+    , external "abstract" (promoteExprR . abstractR :: TH.Name -> RewriteH Core)+        [ "Abstract over a variable using a lambda."+        , "e  ==>  (\\ x -> e) x" ]                                             .+ Shallow .+ Introduce .+ Context+    , external "push" ((\ nm strictf -> push (Just strictf) (cmpTHName2Var nm)) :: TH.Name -> RewriteH Core -> RewriteH Core)+        [ "Push a function 'f into a case-expression or let-expression argument,"+        , "given a proof that f (fully saturated with type arguments) is strict." ] .+ Shallow .+ Commute+    , external "push-unsafe" (push Nothing . cmpTHName2Var :: TH.Name -> RewriteH Core)+        [ "Push a function 'f into a case-expression or let-expression argument."+        , "Requires 'f to be strict." ] .+ Shallow .+ Commute .+ PreCondition+    ]+    ++ Bind.externals+    ++ Case.externals+    ++ Cast.externals+    ++ Let.externals++------------------------------------------------------------------------------++-- | @((\\ v -> e1) e2)@ ==> @(let v = e2 in e1)@+--   This form of beta-reduction is safe if e2 is an arbitrary+--   expression (won't duplicate work).+betaReduceR :: MonadCatch m => Rewrite c m CoreExpr+betaReduceR = setFailMsg ("Beta-reduction failed: " ++ wrongExprForm "App (Lam v e1) e2") $+    do App (Lam v e1) e2 <- idR+       return $ Let (NonRec v e2) e1+++multiBetaReduceR :: MonadCatch m =>  (Int -> Bool) -> Rewrite c m CoreExpr+multiBetaReduceR p = prefixFailMsg "Multi-Beta-Reduce failed: " $+    do+        e <- idR+        let (f,xs) = collectArgs e+        guardMsg (p (length xs)) "incorrect number of arguments."++        let (vs,e0) = collectBinders f++        guardMsg (length vs >= length xs) "insufficent lambdas."++        let (vs1,vs2) = splitAt (length xs) vs++        return+           $ mkLets (zipWith NonRec vs1 xs)+           $ mkLams vs2 e0++-- TODO: inline this everywhere+-- Neil: Are we sure we want to inline this?+-- | Perform one or more beta-reductions.+betaReducePlusR :: MonadCatch m => Rewrite c m CoreExpr+betaReducePlusR = multiBetaReduceR (> 0)++{-++        tagFailR "betaReducePlus failed." $+        appT liftLambda idR App >>> beta_reduce+  where+          -- lift lambda finds the (perhaps hidden) lambda, and brings it out+          liftLambda = observeR "pre-liftLambda" >>> liftLambda' >>> observeR "post-liftLambda"+          liftLambda' =+                   (do e@(Lam {}) <- idR+                       return e)+                <+ (betaReducePlus+                        >>> observeR "liftLambda(UP)"+                            -- let v = e in ...+                            -- TODO: check scope here+                        >>> (do Let bds (Lam v e) <- idR+                                return (Lam v (Let bds e)))+                   )+-}++-- | (let v = e1 in e2) ==> (\\ v -> e2) e1+betaExpandR :: MonadCatch m => Rewrite c m CoreExpr+betaExpandR = setFailMsg ("Beta-expansion failed: " ++ wrongExprForm "Let (NonRec v e1) e2") $+    do Let (NonRec v e1) e2 <- idR+       return $ App (Lam v e2) e1++------------------------------------------------------------------------------++-- | (\\ v -> f v) ==> f+etaReduceR :: MonadCatch m => Rewrite c m CoreExpr+etaReduceR = prefixFailMsg "Eta-reduction failed: " $+            withPatFailMsg (wrongExprForm "Lam v (App f (Var v))") $+            do Lam v1 (App f e) <- idR+               case e of+                  Var v2  -> guardMsg (v1 == v2) "the expression has the right form, but the variables are not equal."+                  Type ty -> case getTyVar_maybe ty of+                               Nothing -> fail "the argument expression is not a type variable."+                               Just v2 -> guardMsg (v1 == v2) "type variables are not equal."+                  _       -> fail "the argument expression is not a variable."+               guardMsg (v1 `notElemVarSet` freeVarsExpr f) $ var2String v1 ++ " is free in the function being applied."+               return f++-- | e1 ==> (\\ v -> e1 v)+etaExpandR :: String -> Rewrite c HermitM CoreExpr+etaExpandR nm = prefixFailMsg "Eta-expansion failed: " $+               contextfreeT $ \ e -> let ty = exprKindOrType e in+        case splitFunTy_maybe ty of+          Just (argTy, _) -> do v <- newIdH nm argTy+                                return $ Lam v (App e (varToCoreExpr v))+          Nothing         -> case splitForAllTy_maybe ty of+                               Just (tv,_) -> do v <- newTyVarH nm (tyVarKind tv)+                                                 return $ Lam v (App e (varToCoreExpr v))+                               Nothing -> fail "type of expression is not a function or a forall."++-- | Perform multiple eta-expansions.+multiEtaExpandR :: (ExtendPath c Crumb, AddBindings c) => [String] -> Rewrite c HermitM CoreExpr+multiEtaExpandR []       = idR+multiEtaExpandR (nm:nms) = etaExpandR nm >>> lamAllR idR (multiEtaExpandR nms)++------------------------------------------------------------------------------++-- | Flatten all the top-level binding groups in the module to a single recursive binding group.+flattenModuleR :: (ExtendPath c Crumb, Monad m) => Rewrite c m ModGuts+flattenModuleR = modGutsR flattenProgramR++-- | Flatten all the top-level binding groups in a program to a program containing a single recursive binding group.+flattenProgramR :: Monad m => Rewrite c m CoreProg+flattenProgramR = do bnd <- flattenProgramT+                     return (bindsToProg [bnd])++-- | Flatten all the top-level binding groups in a program to a single recursive binding group.+flattenProgramT :: Monad m => Translate c m CoreProg CoreBind+flattenProgramT = do bds <- arr (concatMap bindToVarExprs . progToBinds)+                     guardMsg (nodups $ map fst bds) "Top-level bindings contain multiple occurrences of a name."+                     return (Rec bds)++------------------------------------------------------------------------------++-- | Abstract over a variable using a lambda.+--   e  ==>  (\ x. e) x+abstractR :: (ReadBindings c, MonadCatch m) => TH.Name -> Rewrite c m CoreExpr+abstractR nm = prefixFailMsg "abstraction failed: " $+   do e <- idR+      v <- findBoundVarT nm+      return (App (Lam v e) (varToCoreExpr v))++------------------------------------------------------------------------------------------------------++push :: Maybe (RewriteH Core) -- ^ a proof that the function (after being applied to its type arguments) is strict+     -> (Id -> Bool)          -- ^ a predicate to identify the function+     -> RewriteH Core+push mstrict p = promoteExprR (pushR (extractR `fmap` mstrict) p)++-- | Push a function through a Case or Let expression.+--   Unsafe if the function is not strict.+pushR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, HasGlobalRdrEnv c)+      => Maybe (Rewrite c HermitM CoreExpr) -- ^ a proof that the function (after being applied to its type arguments) is strict+      -> (Id -> Bool)                       -- ^ a predicate to identify the function+      -> Rewrite c HermitM CoreExpr+pushR strictf p = prefixFailMsg "push failed: " $+                  withPatFailMsg (wrongExprForm "App f e") $+     do App f e <- idR+        case collectArgs f of+          (Var i,args) -> do+                  guardMsg (p i) $ "identifier not matched."+                  guardMsg (all isTypeArg args) $ "initial arguments are not all type arguments."+                  case e of+                     Case {} -> caseFloatArgR (Just (f,strictf))+                     Let {}  -> letFloatArgR+                     _       -> fail "argument is not a Case or Let."+          _ -> fail "no identifier to match."++------------------------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Local/Bind.hs view
@@ -0,0 +1,47 @@+module HERMIT.Dictionary.Local.Bind+       ( -- * Rewrites on Binding Groups+         externals+       , nonrecToRecR+       , recToNonrecR+       )+where++import HERMIT.Core+import HERMIT.External+import HERMIT.GHC+import HERMIT.Kure++import HERMIT.Dictionary.Common++------------------------------------------------------------------------------++-- | Externals for manipulating binding groups.+externals :: [External]+externals =+    [ external "nonrec-to-rec" (promoteBindR nonrecToRecR :: RewriteH Core)+        [ "Convert a non-recursive binding into a recursive binding group with a single definition."+        , "NonRec v e ==> Rec [Def v e]" ]                           .+ Shallow+    , external "rec-to-nonrec" (promoteBindR recToNonrecR :: RewriteH Core)+        [ "Convert a singleton recursive binding into a non-recursive binding group."+        , "Rec [Def v e] ==> NonRec v e,  (v not free in e)" ]+    ]++------------------------------------------------------------------------------++-- | @'NonRec' v e@ ==> @'Rec' [(v,e)]@+nonrecToRecR :: MonadCatch m => Rewrite c m CoreBind+nonrecToRecR = prefixFailMsg "Converting non-recursive binding to recursive binding failed: " $+               withPatFailMsg (wrongExprForm "NonRec v e") $+  do NonRec v e <- idR+     guardMsg (isId v) "type variables cannot be defined recursively."+     return $ Rec [(v,e)]++-- | @'Rec' [(v,e)]@ ==> @'NonRec' v e@+recToNonrecR :: MonadCatch m => Rewrite c m CoreBind+recToNonrecR = prefixFailMsg "Converting singleton recursive binding to non-recursive binding failed: " $+               withPatFailMsg (wrongExprForm "Rec [Def v e]") $+  do Rec [(v,e)] <- idR+     guardMsg (v `notElemVarSet` freeIdsExpr e) ("'" ++ uqName v ++ " is recursively defined.")+     return (NonRec v e)++------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Local/Case.hs view
@@ -0,0 +1,451 @@+{-# LANGUAGE CPP, MultiWayIf, LambdaCase, ScopedTypeVariables, FlexibleContexts, TupleSections #-}++module HERMIT.Dictionary.Local.Case+    ( -- * Rewrites on Case Expressions+      externals+    , caseFloatAppR+    , caseFloatArgR+    , caseFloatCaseR+    , caseFloatCastR+    , caseFloatLetR+    , caseFloatR+    , caseUnfloatR+    , caseUnfloatAppR+    , caseUnfloatArgsR+    , caseReduceR+    , caseReduceDataconR+    , caseReduceLiteralR+    , caseReduceIdR+    , caseSplitR+    , caseSplitInlineR+    , caseInlineScrutineeR+    , caseInlineAlternativeR+    , caseMergeAltsR+    , caseMergeAltsWithWildR+    , caseElimR+    , caseElimInlineScrutineeR+    , caseElimMergeAltsR+    , caseIntroSeqR+    , caseElimSeqR+    )+where++import Data.List+import Data.Monoid+import Control.Arrow+import Control.Applicative++import HERMIT.Core+import HERMIT.Context+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.GHC+import HERMIT.External+import HERMIT.Utilities+import HERMIT.ParserCore++import HERMIT.Dictionary.Common+import HERMIT.Dictionary.Inline hiding (externals)+import HERMIT.Dictionary.AlphaConversion hiding (externals)+import HERMIT.Dictionary.Fold (foldVarR)+import HERMIT.Dictionary.Undefined (verifyStrictT)++import qualified Language.Haskell.TH as TH++-- NOTE: these are hard to test in small examples, as GHC does them for us, so use with caution+------------------------------------------------------------------------------++-- | Externals relating to Case expressions.+externals :: [External]+externals =+    [ external "case-float-app" (promoteExprR caseFloatAppR :: RewriteH Core)+        [ "(case ec of alt -> e) v ==> case ec of alt -> e v" ]              .+ Commute .+ Shallow+    , external "case-float-arg" ((\ f strict -> promoteExprR (caseFloatArg (Just (f, Just strict)))) :: CoreString -> RewriteH Core -> RewriteH Core)+        [ "For a specific f, given a proof that f is strict, then"+        , "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow+    , external "case-float-arg-unsafe" ((\ f -> promoteExprR (caseFloatArg (Just (f, Nothing)))) :: CoreString -> RewriteH Core)+        [ "For a specific f,"+        , "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow .+ PreCondition+    , external "case-float-arg-unsafe" (promoteExprR (caseFloatArg Nothing) :: RewriteH Core)+        [ "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow .+ PreCondition+    , external "case-float-case" (promoteExprR caseFloatCaseR :: RewriteH Core)+        [ "case (case ec of alt1 -> e1) of alta -> ea ==> case ec of alt1 -> case e1 of alta -> ea" ] .+ Commute .+ Eval+    , external "case-float-cast" (promoteExprR caseFloatCastR :: RewriteH Core)+        [ "cast (case s of p -> e) co ==> case s of p -> cast e co" ]        .+ Shallow .+ Commute+    , external "case-float-let" (promoteExprR caseFloatLetR :: RewriteH Core)+        [ "let v = case ec of alt1 -> e1 in e ==> case ec of alt1 -> let v = e1 in e" ] .+ Commute .+ Shallow+    , external "case-float" (promoteExprR caseFloatR :: RewriteH Core)+        [ "case-float = case-float-app <+ case-float-case <+ case-float-let <+ case-float-cast" ]    .+ Commute .+ Shallow+    , external "case-unfloat" (promoteExprR caseUnfloatR :: RewriteH Core)+        [ "Unfloat a Case whatever the context." ]                             .+ Commute .+ Shallow .+ PreCondition+    , external "case-unfloat-args" (promoteExprR caseUnfloatArgsR :: RewriteH Core)+        [ "Unfloat a Case whose alternatives are parallel applications of the same function." ] .+ Commute .+ Shallow .+ PreCondition+    -- , external "case-unfloat-app" (promoteExprR caseUnfloatApp :: RewriteH Core)+    --     [ "Unfloat a Case whole alternatives are applications of different functions with the same arguments." ] .+ Commute .+ Shallow .+ PreCondition+    , external "case-reduce" (promoteExprR caseReduceR :: RewriteH Core)+        [ "Case of Known Constructor"+        , "case-reduce-datacon <+ case-reduce-literal" ]                     .+ Shallow .+ Eval+    , external "case-reduce-datacon" (promoteExprR caseReduceDataconR :: RewriteH Core)+        [ "Case of Known Constructor"+        , "case C v1..vn of C w1..wn -> e ==> let { w1 = v1 ; .. ; wn = vn } in e" ]    .+ Shallow .+ Eval+    , external "case-reduce-literal" (promoteExprR caseReduceLiteralR :: RewriteH Core)+        [ "Case of Known Constructor"+        , "case L of L -> e ==> e" ]                                         .+ Shallow .+ Eval+    , external "case-reduce-id" (promoteExprR caseReduceIdR :: RewriteH Core)+        [ "Inline the case scrutinee (if it is an identifier) and then case-reduce." ] .+ Shallow .+ Eval .+ Context+    , external "case-split" (promoteExprR . caseSplitR :: TH.Name -> RewriteH Core)+        [ "case-split 'x"+        , "e ==> case x of C1 vs -> e; C2 vs -> e, where x is free in e" ] .+ Shallow+    , external "case-split-inline" (caseSplitInlineR :: TH.Name -> RewriteH Core)+        [ "Like case-split, but additionally inlines the matched constructor "+        , "applications for all occurances of the named variable." ] .+ Deep+    , external "case-intro-seq" (promoteExprR . caseIntroSeqR :: TH.Name -> RewriteH Core)+        [ "Force evaluation of a variable by introducing a case."+        , "case-seq 'v is is equivalent to adding @(seq v)@ in the source code." ] .+ Shallow .+ Introduce+    , external "case-elim-seq" (promoteExprR caseElimSeqR :: RewriteH Core)+        [ "Eliminate a case that corresponds to a pointless seq."  ] .+ Deep .+ Eval+    , external "case-inline-alternative" (promoteExprR caseInlineAlternativeR :: RewriteH Core)+        [ "Inline the case wildcard binder as the case-alternative pattern everywhere in the case alternatives." ] .+ Deep+    , external "case-inline-scrutinee" (promoteExprR caseInlineScrutineeR :: RewriteH Core)+        [ "Inline the case wildcard binder as the case scrutinee everywhere in the case alternatives." ] .+ Deep+    , external "case-merge-alts" (promoteExprR caseMergeAltsR :: RewriteH Core)+        [ "Merge all case alternatives into a single default case."+        , "The RHS of each alternative must be the same."+        , "case s of {pat1 -> e ; pat2 -> e ; ... ; patn -> e} ==> case s of {_ -> e}" ]+    , external "case-merge-alts-with-wild" (promoteExprR caseMergeAltsWithWildR :: RewriteH Core)+        [ "A cleverer version of 'mergeCaseAlts' that first attempts to"+        , "abstract out any occurrences of the alternative pattern using the wildcard binder." ] .+ Deep+    , external "case-elim" (promoteExprR caseElimR :: RewriteH Core)+        [ "case s of w; C vs -> e ==> e if w and vs are not free in e" ]     .+ Shallow+    , external "case-elim-inline-scrutinee" (promoteExprR caseElimInlineScrutineeR :: RewriteH Core)+        [ "Eliminate a case, inlining any occurrences of the case binder as the scrutinee." ] .+ Deep+    , external "case-elim-merge-alts" (promoteExprR caseElimMergeAltsR :: RewriteH Core)+        [ "Eliminate a case, merging the case alternatives into a single default alternative",+          "and inlining the case binder as the scrutinee (if possible)." ] .+ Deep+    , external "case-fold-wild" (promoteExprR caseFoldWildR :: RewriteH Core)+        [ "In the case alternatives, fold any occurrences of the case alt patterns to the wildcard binder." ]+    ]++------------------------------------------------------------------------------++-- | case s of w; C vs -> e ==> e if w and vs are not free in e+caseElimR :: Rewrite c HermitM CoreExpr+caseElimR = prefixFailMsg "Case elimination failed: " $+            withPatFailMsg (wrongExprForm "Case s bnd ty alts") $+ do Case _ bnd _ alts <- idR+    case alts of+        [(_, vs, e)] -> do let fvs = freeVarsExpr e+                           guardMsg (isEmptyVarSet $ intersectVarSet (mkVarSet (bnd:vs)) fvs) "wildcard or pattern binders free in RHS."+                           return e+        _ -> fail "more than one case alternative."++------------------------------------------------------------------------------++-- | (case s of alt1 -> e1; alt2 -> e2) v ==> case s of alt1 -> e1 v; alt2 -> e2 v+caseFloatAppR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatAppR = prefixFailMsg "Case floating from App function failed: " $+  do+    captures    <- appT (map mkVarSet <$> caseAltVarsT) (arr freeVarsExpr) (flip (map . intersectVarSet))+    wildCapture <- appT caseWildIdT (arr freeVarsExpr) elemVarSet+    appT ((if not wildCapture then idR else alphaCaseBinderR Nothing)+          >>> caseAllR idR idR idR (\i -> if isEmptyVarSet (captures !! i) then idR else alphaAltR)+         )+          idR+          (\(Case s b _ alts) v -> let newAlts = mapAlts (`App` v) alts+                                    in Case s b (coreAltsType newAlts) newAlts)++caseFloatArg :: Maybe (CoreString, Maybe (RewriteH Core)) -> RewriteH CoreExpr+caseFloatArg Nothing                 = caseFloatArgR Nothing+caseFloatArg (Just (f_str, mstrict)) =+  do f <- parseCoreExprT f_str+     caseFloatArgR (Just (f, extractR <$> mstrict))++-- | @f (case s of alt1 -> e1; alt2 -> e2)@ ==> @case s of alt1 -> f e1; alt2 -> f e2@+--   Only safe if @f@ is strict.+caseFloatArgR :: (ExtendPath c Crumb, AddBindings c, BoundVars c, HasGlobalRdrEnv c)+              => Maybe (CoreExpr, Maybe (Rewrite c HermitM CoreExpr)) -- ^ Maybe the function to float past, and maybe a proof of its strictness.+              -> Rewrite c HermitM CoreExpr+caseFloatArgR mfstrict = prefixFailMsg "Case floating from App argument failed: " $+                         withPatFailMsg "App f (Case s w ty alts)" $+  do App f (Case s w _ alts) <- idR+     whenJust (\ (f', mstrict) ->+                     do guardMsg (exprAlphaEq f f') "given function does not match current application."+                        whenJust (verifyStrictT f) mstrict+              )+              mfstrict++     let fvs         = freeVarsExpr f+         altCaptures = map (intersectVarSet fvs . mkVarSet . altVars) alts+         wildCapture = elemVarSet w fvs++     if | wildCapture                   -> appAllR idR (alphaCaseBinderR Nothing) >>> caseFloatArgR Nothing+        | all isEmptyVarSet altCaptures -> let new_alts = mapAlts (App f) alts+                                            in return $ Case s w (coreAltsType new_alts) new_alts+        | otherwise                     -> appAllR idR (caseAllR idR idR idR (\ n -> let vs = varSetElems (altCaptures !! n)+                                                                                      in if null vs then idR else alphaAltVarsR vs+                                                                             )+                                                       ) >>> caseFloatArgR Nothing++-- | case (case s1 of alt11 -> e11; alt12 -> e12) of alt21 -> e21; alt22 -> e22+--   ==>+--   case s1 of+--     alt11 -> case e11 of alt21 -> e21; alt22 -> e22+--     alt12 -> case e12 of alt21 -> e21; alt22 -> e22+caseFloatCaseR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatCaseR = prefixFailMsg "Case floating from Case failed: " $+  do+    captures <- caseT (map mkVarSet <$> caseAltVarsT) idR mempty (const $ arr freeVarsAlt) (\ vss w () fvs -> map (intersectVarSet (delVarSet (unionVarSets fvs) w)) vss)+    -- does the binder of the inner case, shadow a free variable in any of the outer case alts?+    wildCapture <- caseT caseWildIdT idR mempty (const $ arr freeVarsAlt) (\ innerBndr w () fvs -> innerBndr `elemVarSet` (delVarSet (unionVarSets fvs) w))+    caseT ((if not wildCapture then idR else alphaCaseBinderR Nothing)+           >>> caseAllR idR idR idR (\i -> if isEmptyVarSet (captures !! i) then idR else alphaAltR)+          )+          idR+          idR+          (const idR)+          (\ (Case s1 b1 _ alts1) b2 ty alts2 -> Case s1 b1 ty $ mapAlts (\s -> Case s b2 ty alts2) alts1)++-- | let v = case s of alt1 -> e1 in e ==> case s of alt1 -> let v = e1 in e+caseFloatLetR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatLetR = prefixFailMsg "Case floating from Let failed: " $+  do vs <- letNonRecT idR caseAltVarsT mempty (\ letVar caseVars () -> letVar `elem` concat caseVars)+     let bdsAction = if not vs then idR else nonRecAllR idR alphaCaseR+     letT bdsAction idR $ \ (NonRec v (Case s b _ alts)) e -> let newAlts = mapAlts (\ rhs -> Let (NonRec v rhs) e) alts+                                                               in Case s b (coreAltsType newAlts) newAlts++-- | cast (case s of p -> e) co ==> case s of p -> cast e co+caseFloatCastR :: MonadCatch m => Rewrite c m CoreExpr+caseFloatCastR = prefixFailMsg "Case float from cast failed: " $+                withPatFailMsg (wrongExprForm "Cast (Case s bnd ty alts) co") $+    do Cast (Case s bnd _ alts) co <- idR+       let alts' = mapAlts (flip Cast co) alts+       return $ Case s bnd (coreAltsType alts') alts'++-- | caseFloatR = caseFloatAppR <+ caseFloatCaseR <+ caseFloatLetR <+ caseFloatCastR+--   Note: does NOT include caseFloatArg+caseFloatR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFloatR = setFailMsg "Unsuitable expression for Case floating." $+    caseFloatAppR <+ caseFloatCaseR <+ caseFloatLetR <+ caseFloatCastR++------------------------------------------------------------------------------++-- | Unfloat a Case whatever the context.+caseUnfloatR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr+caseUnfloatR = setFailMsg "Case unfloating failed." $+    caseUnfloatAppR <+ caseUnfloatArgsR++-- | Unimplemented!+caseUnfloatAppR :: Monad m => Rewrite c m CoreExpr+caseUnfloatAppR = fail "caseUnfloatApp: TODO"++caseUnfloatArgsR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr+caseUnfloatArgsR = prefixFailMsg "Case unfloating into arguments failed: " $+                   withPatFailMsg (wrongExprForm "Case s v t alts") $+    do Case s wild _ty alts <- idR+       (vss, fs, argss) <- caseT mempty mempty mempty (\ _ -> altT mempty (\ _ -> idR) callT $ \ () vs (fn, args) -> (vs, fn, args))+                                                      (\ () () () alts' -> unzip3 [ (wild:vs, fn, args) | (vs,fn,args) <- alts' ])+       guardMsg (equivalentBy exprAlphaEq fs) "alternatives are not parallel in function call."+       let fvs = [ varSetElems $ unionVarSets $ map freeVarsExpr $ f:tyArgs+                 | (f,args) <- zip fs argss+                 , let tyArgs = takeWhile isTyCoArg args ] -- pattern binders can be existential types+       guardMsg (all null $ zipWith intersect fvs vss) "function bound by case binders."+       let argss' = transpose argss+       guardMsg (all (equivalentBy exprAlphaEq) $ filter (isTyCoArg . head) argss') "function applied at different types."+       return $ mkCoreApps (head fs) [ if isTyCoArg (head args)+                                       then head args+                                       else let alts' = [ (ac, vs, arg) | ((ac,vs,_),arg) <- zip alts args ]+                                            in Case s wild (coreAltsType alts') alts'+                                     | args <- argss' ]++------------------------------------------------------------------------------++-- | Inline the case scrutinee (if it is an identifier), and then perform case reduction.+caseReduceIdR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseReduceIdR = caseAllR inlineR idR idR (const idR) >>> caseReduceR++-- | Case of Known Constructor.+--   Eliminate a case if the scrutinee is a data constructor or a literal.+caseReduceR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseReduceR = setFailMsg "Unsuitable expression for Case reduction." $+              caseReduceDataconR <+ caseReduceLiteralR++-- | Case of Known Constructor.+--   Eliminate a case if the scrutinee is a literal.+-- NB: LitAlt cases don't do evaluation+caseReduceLiteralR :: MonadCatch m => Rewrite c m CoreExpr+caseReduceLiteralR = prefixFailMsg "Case reduction failed: " $+                     withPatFailMsg (wrongExprForm "Case (Lit l) v t alts") $+    do Case s wild _ alts <- idR+#if __GLASGOW_HASKELL__ > 706+       let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- varSetElems (localFreeVarsExpr s) ])+       case exprIsLiteral_maybe (in_scope, idUnfolding) s of+#else+       case exprIsLiteral_maybe idUnfolding s of+#endif+        Nothing -> fail "scrutinee is not a literal."+        Just l  -> do guardMsg (not (litIsLifted l)) "cannot case-reduce lifted literals" -- see Trac #5603+                      case findAlt (LitAlt l) alts of+                        Nothing          -> fail "no matching alternative."+                        Just (_, _, rhs) -> return $ mkCoreLet (NonRec wild (Lit l)) rhs++-- | Case of Known Constructor.+--   Eliminate a case if the scrutinee is a data constructor.+caseReduceDataconR :: forall c. (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseReduceDataconR = prefixFailMsg "Case reduction failed: " $+                     withPatFailMsg (wrongExprForm "Case e v t alts")+                     go+  where+    go :: Rewrite c HermitM CoreExpr+    go = do Case e wild _ alts <- idR+#if __GLASGOW_HASKELL__ > 706+            let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- varSetElems (localFreeVarsExpr e) ])+            case exprIsConApp_maybe (in_scope, idUnfolding) e of+#else+            case exprIsConApp_maybe idUnfolding e of+#endif+              Nothing                -> fail "head of scrutinee is not a data constructor."+              Just (dc, univTys, es) -> case findAlt (DataAlt dc) alts of+                Nothing             -> fail "no matching alternative."+                Just (dc', vs, rhs) -> -- dc' is either DEFAULT or dc+                                       -- NB: It is possible that es contains one or more existentially quantified types.+                                       let fvss    = map freeVarsExpr $ map Type univTys ++ es+                                           shadows = [ v | (v,n) <- zip vs [1..], any (elemVarSet v) (drop n fvss) ]+                                       in if | any (elemVarSet wild) fvss -> alphaCaseBinderR Nothing >>> go+                                             | null shadows               -> return $ flip mkCoreLets rhs $ zipWith NonRec (wild : vs) (e : es)+                                             | otherwise                  -> caseOneR (fail "scrutinee") (fail "binder") (fail "type") (\ _ -> acceptR (\ (dc'',_,_) -> dc'' == dc') >>> alphaAltVarsR shadows) >>> go+-- WARNING: The alpha-renaming to avoid variable capture has not been tested.  We need testing infrastructure!++-- | Case split a free identifier in an expression:+--+-- E.g. Assume expression e which mentions i :: [a]+--+-- e ==> case i of i+--         []     -> e+--         (a:as) -> e+caseSplitR :: TH.Name -> Rewrite c HermitM CoreExpr+caseSplitR nm = prefixFailMsg "caseSplit failed: " $+               do i <- matchingFreeIdT nm+                  let (tycon, tys) = splitTyConApp (idType i)+                      aNms         = map (:[]) $ cycle ['a'..'z']+                  contextfreeT $ \ e -> do dcsAndVars <- mapM (\ dc -> (dc,) <$> sequence [ newIdH a ty | (a,ty) <- zip aNms $ dataConInstArgTys dc tys ])+                                                              (tyConDataCons tycon)+                                           let alts = [ (DataAlt dc, as, e) | (dc,as) <- dcsAndVars ]+                                           return $ Case (Var i) i (coreAltsType alts) alts++-- | Force evaluation of an identifier by introducing a case.+--   This is equivalent to adding @(seq v)@ in the source code.+--+-- e -> case v of v+--        _ -> e+caseIntroSeqR :: TH.Name -> Rewrite c HermitM CoreExpr+caseIntroSeqR nm = prefixFailMsg "case-intro-seq failed: " $+             do i <- matchingFreeIdT nm+                e <- idR+                guardMsg (not $ isTyCoArg e) "cannot case on a type or coercion."+                let alts = [(DEFAULT, [], e)]+                return $ Case (Var i) i (coreAltsType alts) alts++-- auxillary function for use by caseSplit and caseSeq+matchingFreeIdT :: Monad m => TH.Name -> Translate c m CoreExpr Id+matchingFreeIdT nm = do+  fvs <- arr freeVarsExpr+  case varSetElems (filterVarSet (\ v -> cmpTHName2Var nm v && isId v) fvs) of+    []    -> fail "provided name is not a free identifier."+    [i]   -> return i+    is    -> fail ("provided name matches " ++ show (length is) ++ " free identifiers.")++-- | Like caseSplit, but additionally inlines the constructor applications+-- for each occurance of the named variable.+--+-- > caseSplitInline nm = caseSplit nm >>> anybuR (inlineName nm)+caseSplitInlineR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM Core+caseSplitInlineR nm = promoteR (caseSplitR nm) >>> anybuR (promoteExprR $ inlineNameR nm)++------------------------------------------------------------------------------++caseInlineBinderR :: forall c. (ExtendPath c Crumb, AddBindings c, ReadBindings c) => CaseBinderInlineOption -> Rewrite c HermitM CoreExpr+caseInlineBinderR opt =+  do w <- caseWildIdT+     caseAllR idR idR idR $ \ _ -> setFailMsg "no inlinable occurrences." $+                                   do depth <- varBindingDepthT w+                                      extractR $ anybuR (promoteExprR (configurableInlineR (CaseBinderOnly opt) (varIsOccurrenceOfT w depth)) :: Rewrite c HermitM Core)++-- | Inline the case wildcard binder as the case scrutinee everywhere in the case alternatives.+caseInlineScrutineeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseInlineScrutineeR = prefixFailMsg "case-inline-scrutinee failed: " $+                       caseInlineBinderR Scrutinee++-- | Inline the case wildcard binder as the case-alternative pattern everywhere in the case alternatives.+caseInlineAlternativeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseInlineAlternativeR = prefixFailMsg "case-inline-alternative failed: " $+                         caseInlineBinderR Alternative++------------------------------------------------------------------------------++-- | Merge all case alternatives into a single default case.+--   The RHS of each alternative must be the same.+--   @case s of {pat1 -> e ; pat2 -> e ; ... ; patn -> e}@ ==> @case s of {_ -> e}@+caseMergeAltsR :: MonadCatch m => Rewrite c m CoreExpr+caseMergeAltsR = prefixFailMsg "merge-case-alts failed: " $+                 withPatFailMsg (wrongExprForm "Case e w ty alts") $+                 do Case e w ty alts <- idR+                    guardMsg (notNull alts) "zero alternatives cannot be merged."+                    let rhss = [ rhs | (_,_,rhs) <- alts ]+                    guardMsg (equivalentBy exprAlphaEq rhss) "right-hand sides are not all equal."+                    guardMsg (all altVarsUnused alts) "variables bound in case alt pattern appear free in alt right-hand side."+                    return $ Case e w ty [(DEFAULT,[],head rhss)]++-- | In the case alternatives, fold any occurrences of the case alt patterns to the wildcard binder.+caseFoldWildR :: forall c.  (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseFoldWildR = prefixFailMsg "case-fold-wild failed: " $+                do w <- caseWildIdT+                   caseAllR idR idR idR $ \ _ -> do depth <- varBindingDepthT w+                                                    extractR $ anybuR (promoteExprR (foldVarR w (Just depth)) :: Rewrite c HermitM Core)++-- | A cleverer version of 'mergeCaseAlts' that first attempts to abstract out any occurrences of the alternative pattern using the wildcard binder.+caseMergeAltsWithWildR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseMergeAltsWithWildR = prefixFailMsg "merge-case-alts-with-wild failed: " $+                         withPatFailMsg (wrongExprForm "Case e w ty alts") $+                         tryR caseFoldWildR >>> caseMergeAltsR++-- | Eliminate a case, inlining any occurrences of the case binder as the scrutinee.+caseElimInlineScrutineeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseElimInlineScrutineeR = alphaCaseBinderR Nothing >>> tryR caseInlineScrutineeR >>> caseElimR++-- | Eliminate a case, merging the case alternatives into a single default alternative and inlining the case binder as the scrutinee (if possible).+caseElimMergeAltsR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseElimMergeAltsR = tryR caseFoldWildR >>> tryR caseMergeAltsR >>> caseElimInlineScrutineeR++------------------------------------------------------------------------------++-- | Eliminate a case that corresponds to a pointless 'seq'.+caseElimSeqR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+caseElimSeqR = prefixFailMsg "case-elim-seq failed: " $+               withPatFailMsg "not a seq case." $+  do Case s w _ [(DEFAULT,[],rhs)] <- idR++     let is = case s of+                Var i -> [i,w]+                _     -> [w]++     if is `isForcedIn` rhs+       then caseElimInlineScrutineeR+       else fail "cannot be sure that this seq case is pointless.  Use case-elim-inline-scrutinee if you want to proceed anyway."++-- | Will forcing the expression to WHNF always force one of the given identifiers?+isForcedIn :: [Id] -> CoreExpr -> Bool+isForcedIn is = \case+                   Var i         -> i `elem` is+                   App f _       -> is `isForcedIn` f+                   Let _ body    -> is `isForcedIn` body+                   Case s _ _ _  -> is `isForcedIn` s+                   Cast e _      -> is `isForcedIn` e+                   Tick _ e      -> is `isForcedIn` e+                   _             -> False++------------------------------------------------------------------------------++altVarsUnused :: CoreAlt -> Bool+altVarsUnused (_,vs,rhs) = all (`notElemVarSet` freeVarsExpr rhs) vs++------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Local/Cast.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE CPP, FlexibleContexts #-}++module HERMIT.Dictionary.Local.Cast+    ( -- * Rewrites on Case Expressions+      externals+    , castElimReflR+    , castElimSymR+    , castFloatAppR+    , castElimSymPlusR -- TODO: revisit+    )+where++import qualified Coercion (substCo, extendTvSubst)++import Control.Arrow+import Control.Monad++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC++import HERMIT.Dictionary.Common++------------------------------------------------------------------------------++-- | Externals relating to Case expressions.+externals :: [External]+externals =+    [ external "cast-elim" (promoteExprR castElimR :: RewriteH Core)+        [ "cast-elim-refl <+ cast-elim-sym" ] .+ Shallow -- don't include in "Bash", as sub-rewrites are tagged "Bash" already.+    , external "cast-elim-refl" (promoteExprR castElimReflR :: RewriteH Core)+        [ "cast e co ==> e ; if co is a reflexive coercion" ] .+ Shallow+    , external "cast-elim-sym" (promoteExprR castElimSymR :: RewriteH Core)+        [ "removes pairs of symmetric casts" ]                .+ Shallow+    , external "cast-elim-sym-plus" (promoteExprR castElimSymPlusR :: RewriteH Core)+        [ "removes pairs of symmetric casts possibly separated by let or case forms" ] .+ Deep .+ TODO+    , external "cast-float-app" (promoteExprR castFloatAppR :: RewriteH Core)+        [ "(cast e (c1 -> c2)) x ==> cast (e (cast x (sym c1))) c2" ] .+ Shallow+    , external "cast-elim-unsafe" (promoteExprR castElimUnsafeR :: RewriteH Core)+        [ "removes casts regardless of whether it is safe to do so" ] .+ Shallow .+ Experiment .+ Unsafe .+ TODO+    ]++------------------------------------------------------------------------------++castElimR :: MonadCatch m => Rewrite c m CoreExpr+castElimR = setFailMsg "Cast elimination failed: " $+            castElimReflR <+ castElimSymR++castElimReflR :: MonadCatch m => Rewrite c m CoreExpr+castElimReflR = prefixFailMsg "Reflexive cast elimination failed: " $+                withPatFailMsg (wrongExprForm "Cast e co") $+    do Cast e co <- idR+       Pair a b <- return $ coercionKind co+       guardMsg (eqType a b) "not a reflexive coercion."+       return e++castElimSymR :: MonadCatch m => Rewrite c m CoreExpr+castElimSymR = prefixFailMsg "Symmetric cast elimination failed: " $+               withPatFailMsg (wrongExprForm "Cast (Cast e co1) co2") $+    do Cast (Cast e co1) co2 <- idR+       let Pair a b   = coercionKind co1+           Pair b' a' = coercionKind co2+       guardMsg (eqType a a' && eqType b b') "coercions are not symmetric."+       return e++castFloatAppR :: MonadCatch m => Rewrite c m CoreExpr+castFloatAppR = prefixFailMsg "Cast float from application failed: " $+                withPatFailMsg (wrongExprForm "App (Cast e1 co) e2") $+    do App (Cast e1 co) e2 <- idR+       case co of+#if __GLASGOW_HASKELL__ > 706+            TyConAppCo _r t [c1, c2] -> do+#else+            TyConAppCo t [c1, c2] -> do+#endif+                True <- return (isFunTyCon t)+                return $ Cast (App e1 (Cast e2 (SymCo c1))) c2+            ForAllCo t c2 -> do+                Type x' <- return e2+                return (Cast (App e1 e2) (Coercion.substCo (Coercion.extendTvSubst emptyCvSubst t x') c2))+            _ -> fail "castFloatApp"++#if __GLASGOW_HASKELL__ > 706+-- | Attempts to tease a coercion apart into a type constructor and the application+-- of a number of coercion arguments to that constructor+splitTyConAppCo_maybe :: Coercion -> Maybe (TyCon, [Coercion])+splitTyConAppCo_maybe (Refl ro ty)          = (fmap . second . map) (Refl ro) (splitTyConApp_maybe ty)+splitTyConAppCo_maybe (TyConAppCo _r tc cs) = Just (tc, cs)+splitTyConAppCo_maybe _                     = Nothing+#endif++-- TODO: revisit+castElimSymPlusR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr+castElimSymPlusR = castT idR idR (flip go) >>> joinT+  where+      go :: Monad m => Coercion -> CoreExpr -> m CoreExpr+      go _  (Var _) = fail "no symmetric casts found"+      go _  (Lit _) = fail "no symmetric casts found"+      go _  (App _ _) = fail "app unimplemented" {- focus [0] (go c1 (add arg)) -}+      go c1 (Lam x body)+        | Just (con, [arg, res]) <- splitTyConAppCo_maybe c1+        , con == funTyCon+        , Pair arg1 arg2 <- coercionKind arg+        , arg1 `eqType` arg2 = do+            body' <- go res body+            return (Lam x body')+        | otherwise = fail "lam unimplemented" {-focus [0] (go c1 (drop arg))-}+      go c1 (Let bs body) = do body' <- go c1 body+                               return (Let bs body')+      go c1 (Case scr x _ alts) = do alts' <- sequence [liftM ((,,) c a) (go c1 b) | (c,a,b) <- alts]+                                     let t' = exprType (case head alts' of (_,_,b) -> b)+                                     return (Case scr x t' alts')+      go c1 (Cast e c2) = if sym c1 c2 then return e else fail "no symmetric casts found"+      go _  (Tick{}) = fail "unexpected tick"+      go _  (Type{}) = fail "unexpected type"+      go _  (Coercion{}) = fail "unexpected coercion"++      sym :: Coercion -> Coercion -> Bool+      sym c1 c2+        | Pair c11 c12 <- coercionKind c1,+          Pair c21 c22 <- coercionKind c2,+          c11 `eqType` c22, c21 `eqType` c12 = True+        | otherwise = False+      --sym (SymCo c1) c2 = geq c1 c2+      --sym c1 (SymCo c2) = geq c1 c2+      --sym _ _ = False+++castElimUnsafeR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr+castElimUnsafeR = castT idR idR const+
+ src/HERMIT/Dictionary/Local/Let.hs view
@@ -0,0 +1,426 @@+{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}++module HERMIT.Dictionary.Local.Let+       ( -- * Rewrites on Let Expressions+         externals+         -- ** Let Elimination+       , letNonRecSubstR+       , letNonRecSubstSafeR+       , letSubstR+       , letSubstSafeR+       , letElimR+       , letNonRecElimR+       , letRecElimR+         -- ** Let Introduction+       , letIntroR+         -- ** Let Floating+       , letFloatAppR+       , letFloatArgR+       , letFloatLetR+       , letFloatLamR+       , letFloatCaseR+       , letFloatCastR+       , letFloatExprR+       , letFloatTopR+         -- ** Let Unfloating+       , letUnfloatR+       , letUnfloatAppR+       , letUnfloatCaseR+       , letUnfloatLamR+         -- ** Miscallaneous+       , reorderNonRecLetsR+       , letTupleR+       , letToCaseR+       )+where++import Control.Arrow+import Control.Monad++import Data.List+import Data.Monoid++import HERMIT.Core+import HERMIT.Context+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC+import HERMIT.Utilities++import HERMIT.Dictionary.Common+import HERMIT.Dictionary.GHC hiding (externals)+import HERMIT.Dictionary.AlphaConversion hiding (externals)++import HERMIT.Dictionary.Local.Bind hiding (externals)++import qualified Language.Haskell.TH as TH++------------------------------------------------------------------------------++-- | Externals relating to 'Let' expressions.+externals :: [External]+externals =+    [ external "let-subst" (promoteExprR letSubstR :: RewriteH Core)+        [ "Let substitution: (let x = e1 in e2) ==> (e2[e1/x])"+        , "x must not be free in e1." ]                                         .+ Deep .+ Eval+    , external "let-subst-safe" (promoteExprR letSubstSafeR :: RewriteH Core)+        [ "Safe let substitution"+        , "let x = e1 in e2, safe to inline without duplicating work ==> e2[e1/x],"+        , "x must not be free in e1." ]                                         .+ Deep .+ Eval+    -- , external "safe-let-subst-plus" (promoteExprR safeLetSubstPlusR :: RewriteH Core)+    --     [ "Safe let substitution"+    --     , "let { x = e1, ... } in e2, "+    --     , "  where safe to inline without duplicating work ==> e2[e1/x,...],"+    --     , "only matches non-recursive lets" ]  .+ Deep .+ Eval+    , external "let-intro" (promoteExprR . letIntroR . show :: TH.Name -> RewriteH Core)+        [ "e => (let v = e in v), name of v is provided" ]                      .+ Shallow .+ Introduce+    , external "let-elim" (promoteExprR letElimR :: RewriteH Core)+        [ "Remove an unused let binding."+        , "(let v = e1 in e2) ==> e2, if v is not free in e1 or e2." ]          .+ Eval .+ Shallow+--    , external "let-constructor-reuse" (promoteR $ not_defined "constructor-reuse" :: RewriteH Core)+--        [ "let v = C v1..vn in ... C v1..vn ... ==> let v = C v1..vn in ... v ..., fails otherwise" ] .+ Eval+    , external "let-float-app" (promoteExprR letFloatAppR :: RewriteH Core)+        [ "(let v = ev in e) x ==> let v = ev in e x" ]                         .+ Commute .+ Shallow+    , external "let-float-arg" (promoteExprR letFloatArgR :: RewriteH Core)+        [ "f (let v = ev in e) ==> let v = ev in f e" ]                         .+ Commute .+ Shallow+    , external "let-float-lam" (promoteExprR letFloatLamR :: RewriteH Core)+        [ "The Full Laziness Transformation"+        , "(\\ v1 -> let v2 = e1 in e2)  ==>  let v2 = e1 in (\\ v1 -> e2), if v1 is not free in e2."+        , "If v1 = v2 then v1 will be alpha-renamed." ]                         .+ Commute .+ Shallow+    , external "let-float-let" (promoteExprR letFloatLetR :: RewriteH Core)+        [ "let v = (let w = ew in ev) in e ==> let w = ew in let v = ev in e" ] .+ Commute .+ Shallow+    , external "let-float-case" (promoteExprR letFloatCaseR :: RewriteH Core)+        [ "case (let v = ev in e) of ... ==> let v = ev in case e of ..." ]     .+ Commute .+ Shallow .+ Eval+    , external "let-float-cast" (promoteExprR letFloatCastR :: RewriteH Core)+        [ "cast (let bnds in e) co ==> let bnds in cast e co" ]                 .+ Commute .+ Shallow+    , external "let-float-top" (promoteProgR letFloatTopR :: RewriteH Core)+        [ "v = (let bds in e) : prog ==> bds : v = e : prog" ]                  .+ Commute .+ Shallow+    , external "let-float" (promoteProgR letFloatTopR <+ promoteExprR letFloatExprR :: RewriteH Core)+        [ "Float a Let whatever the context." ]                                 .+ Commute .+ Shallow  -- Don't include in bash, as each sub-rewrite is tagged "Bash" already.+    , external "let-to-case" (promoteExprR letToCaseR :: RewriteH Core)+        [ "let v = ev in e ==> case ev of v -> e" ]                             .+ Commute .+ Shallow .+ PreCondition+--    , external "let-to-case-unbox" (promoteR $ not_defined "let-to-case-unbox" :: RewriteH Core)+--        [ "let v = ev in e ==> case ev of C v1..vn -> let v = C v1..vn in e" ]+    , external "let-unfloat" (promoteExprR letUnfloatR :: RewriteH Core)+        [ "Unfloat a let if possible." ]                                        .+ Commute .+ Shallow+    , external "let-unfloat-app" ((promoteExprR letUnfloatAppR >+> anybuR (promoteExprR letElimR)) :: RewriteH Core)+        [ "let v = ev in f a ==> (let v = ev in f) (let v = ev in a)" ]         .+ Commute .+ Shallow+    , external "let-unfloat-case" ((promoteExprR letUnfloatCaseR >+> anybuR (promoteExprR letElimR)) :: RewriteH Core)+        [ "let v = ev in case s of p -> e ==> case (let v = ev in s) of p -> let v = ev in e"+        , "if v does not shadow a pattern binder in p" ]                        .+ Commute .+ Shallow+    , external "let-unfloat-lam" ((promoteExprR letUnfloatLamR >+> anybuR (promoteExprR letElimR)) :: RewriteH Core)+        [ "let v = ev in \\ x -> e ==> \\ x -> let v = ev in e"+        , "if v does not shadow x" ]                                            .+ Commute .+ Shallow+    , external "reorder-lets" (promoteExprR . reorderNonRecLetsR :: [TH.Name] -> RewriteH Core)+        [ "Re-order a sequence of nested non-recursive let bindings."+        , "The argument list should contain the let-bound variables, in the desired order." ]+    , external "let-tuple" (promoteExprR . letTupleR . show :: TH.Name -> RewriteH Core)+        [ "Combine nested non-recursive lets into case of a tuple."+        , "E.g. let {v1 = e1 ; v2 = e2 ; v3 = e3} in body ==> case (e1,e2,e3) of {(v1,v2,v3) -> body}" ] .+ Commute+    ]++-------------------------------------------------------------------------------------------++-- | (let x = e1 in e2) ==> (e2[e1/x]), (x must not be free in e1)+letSubstR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr+letSubstR = letAllR (tryR recToNonrecR) idR >>> letNonRecSubstR++-- | As 'letNonRecSubstSafeR', but attempting to convert a singleton recursive binding to a non-recursive binding first.+letSubstSafeR :: (AddBindings c, ExtendPath c Crumb, ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr+letSubstSafeR = letAllR (tryR recToNonrecR) idR >>> letNonRecSubstSafeR++-- | @Let (NonRec v e) body@ ==> @body[e/v]@+letNonRecSubstR :: MonadCatch m => Rewrite c m CoreExpr+letNonRecSubstR = prefixFailMsg "Let substitution failed: " $+                  withPatFailMsg (wrongExprForm "Let (NonRec v rhs) body") $+    do Let (NonRec v rhs) body <- idR+       return body >>> substExprR v rhs++-- | Currently we always substitute types and coercions, and use a heuristic to decide whether to substitute expressions.+--   This may need revisiting.+letNonRecSubstSafeR :: forall c m. (AddBindings c, ExtendPath c Crumb, ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr+letNonRecSubstSafeR =+    do Let (NonRec v _) _ <- idR+       when (isId v) $ guardMsgM (safeSubstT v) "safety criteria not met."+       letNonRecSubstR+  where+    safeSubstT :: Id -> Translate c m CoreExpr Bool+    safeSubstT i = letNonRecT mempty safeBindT (safeOccursT i) (\ () -> (||))++    -- what about other Expr constructors, e.g Cast?+    safeBindT :: Translate c m CoreExpr Bool+    safeBindT =+      do c <- contextT+         arr $ \ e ->+           case e of+             Var {} -> True+             Lam {} -> True+             App {} -> case collectArgs e of+                         (Var f,args) -> arityOf c f > length (filter (not . isTyCoArg) args) -- Neil: I've changed this to "not . isTyCoArg" rather than "not . isTypeArg".+                                                                                              -- This may not be the right thing to do though.+                         (other,args) -> case collectBinders other of+                                           (bds,_) -> length bds > length args+             _      -> False++    safeOccursT :: Id -> Translate c m CoreExpr Bool+    safeOccursT i =+      do depth <- varBindingDepthT i+         let occursHereT :: Translate c m Core ()+             occursHereT = promoteExprT (exprIsOccurrenceOfT i depth >>> guardT)++             -- lamOccurrenceT can only fail if the expression is not a Lam+             -- return either 2 (occurrence) or 0 (no occurrence)+             lamOccurrenceT :: Translate c m CoreExpr (Sum Int)+             lamOccurrenceT =  lamT mempty+                                    (mtryM (Sum 2 <$ extractT (onetdT occursHereT)))+                                    mappend++             occurrencesT :: Translate c m Core (Sum Int)+             occurrencesT = prunetdT (promoteExprT lamOccurrenceT <+ (Sum 1 <$ occursHereT))++         extractT occurrencesT >>^ (getSum >>> (< 2))++(<$) :: Monad m => a -> m b -> m a+a <$ mb = mb >> return a++-------------------------------------------------------------------------------------------++-- | @e@ ==> @(let v = e in v)@, name of v is provided+letIntroR :: String -> Rewrite c HermitM CoreExpr+letIntroR nm = prefixFailMsg "Let-introduction failed: " $+              contextfreeT $ \ e -> do guardMsg (not $ isTypeArg e) "let expressions may not return a type."+                                       v <- newIdH nm (exprKindOrType e)+                                       return $ Let (NonRec v e) (Var v)++-------------------------------------------------------------------------------------------++letElimR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr+letElimR = prefixFailMsg "Let elimination failed: " $+          withPatFailMsg (wrongExprForm "Let binds expr") $+          do Let bg _ <- idR+             case bg of+               NonRec{} -> letNonRecElimR+               Rec{}    -> letRecElimR++-- | Remove an unused non-recursive let binding.+--   @let v = E1 in E2@ ==> @E2@, if @v@ is not free in @E2@+letNonRecElimR :: MonadCatch m => Rewrite c m CoreExpr+letNonRecElimR = withPatFailMsg (wrongExprForm "Let (NonRec v e1) e2") $+                do Let (NonRec v _) e <- idR+                   guardMsg (v `notElemVarSet` freeVarsExpr e) "let-bound variable appears in the expression."+                   return e++-- | Remove all unused recursive let bindings in the current group.+letRecElimR :: MonadCatch m => Rewrite c m CoreExpr+letRecElimR = withPatFailMsg (wrongExprForm "Let (Rec v e1) e2") $+    do Let (Rec bnds) body <- idR+       let bodyFrees   = freeIdsExpr body+           bsAndFrees  = map (second freeIdsExpr) bnds+           usedIds     = chaseDependencies bodyFrees bsAndFrees+           bs          = mkVarSet (map fst bsAndFrees)+           liveBinders = bs `intersectVarSet` usedIds+       if isEmptyVarSet liveBinders+          then return body+          else if bs `subVarSet` liveBinders+                 then fail "no dead binders to eliminate."+                 else return $ Let (Rec $ filter ((`elemVarSet` liveBinders) . fst) bnds) body+  where+    chaseDependencies :: VarSet -> [(Var,VarSet)] -> VarSet+    chaseDependencies usedIds bsAndFrees = case partition ((`elemVarSet` usedIds) . fst) bsAndFrees of+                                              ([],_)        -> usedIds+                                              (used,unused) -> chaseDependencies (unionVarSets (usedIds : map snd used)) unused++-------------------------------------------------------------------------------------------++-- | @let v = ev in e@ ==> @case ev of v -> e@+letToCaseR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+letToCaseR = prefixFailMsg "Converting Let to Case failed: " $+            withPatFailMsg (wrongExprForm "Let (NonRec v e1) e2") $+  do Let (NonRec v ev) _ <- idR+     guardMsg (not $ isTyCoArg ev) "cannot case on a type or coercion."+     nameModifier <- freshNameGenT Nothing+     caseBndr <- constT (cloneVarH nameModifier v)+     letT mempty (replaceVarR v caseBndr) $ \ () e' -> Case ev caseBndr (varType v) [(DEFAULT, [], e')]++-------------------------------------------------------------------------------------------++-- | @(let v = ev in e) x@ ==> @let v = ev in e x@+letFloatAppR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatAppR = prefixFailMsg "Let floating from App function failed: " $+               withPatFailMsg (wrongExprForm "App (Let bnds body) e") $+  do App (Let bnds body) e <- idR+     let vs = mkVarSet (bindVars bnds) `intersectVarSet` freeVarsExpr e+     if isEmptyVarSet vs+        then return $ Let bnds (App body e)+        else appAllR (alphaLetVarsR $ varSetElems vs) idR >>> letFloatAppR++-- | @f (let v = ev in e)@ ==> @let v = ev in f e@+letFloatArgR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatArgR = prefixFailMsg "Let floating from App argument failed: " $+               withPatFailMsg (wrongExprForm "App f (Let bnds body)") $+  do App f (Let bnds body) <- idR+     let vs = mkVarSet (bindVars bnds) `intersectVarSet` freeVarsExpr f+     if isEmptyVarSet vs+        then return $ Let bnds (App f body)+        else appAllR idR (alphaLetVarsR $ varSetElems vs) >>> letFloatArgR++-- | @let v = (let bds in e1) in e2@ ==> @let bds in let v = e1 in e2@+letFloatLetR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatLetR = prefixFailMsg "Let floating from Let failed: " $+               withPatFailMsg (wrongExprForm "Let (NonRec v (Let bds e1)) e2") $+  do Let (NonRec v (Let bds e1)) e2 <- idR+     let vs = mkVarSet (bindVars bds) `intersectVarSet` freeVarsExpr e2+     if isEmptyVarSet vs+       then return $ Let bds (Let (NonRec v e1) e2)+       else letNonRecAllR idR (alphaLetVarsR $ varSetElems vs) idR >>> letFloatLetR++-- | @(\ v -> let binds in e2)@  ==>  @let binds in (\ v1 -> e2)@+--   Fails if @v@ occurs in the RHS of @binds@.+--   If @v@ is shadowed in binds, then @v@ will be alpha-renamed.+letFloatLamR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatLamR = prefixFailMsg "Let floating from Lam failed: " $+               withPatFailMsg (wrongExprForm "Lam v1 (Let bds body)") $+  do Lam v (Let binds body) <- idR+     let bs  = bindVars binds+         fvs = freeVarsBind binds+     guardMsg (v `notElemVarSet` fvs) (var2String v ++ " occurs in the RHS of the let-bindings.")+     if v `elem` bs+      then alphaLamR Nothing >>> letFloatLamR+      else return $ Let binds (Lam v body)++-- | @case (let bnds in e) of wild alts@ ==> @let bnds in (case e of wild alts)@+--   Fails if any variables bound in @bnds@ occurs in @alts@.+letFloatCaseR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatCaseR = prefixFailMsg "Let floating from Case failed: " $+                withPatFailMsg (wrongExprForm "Case (Let bnds e) w ty alts") $+  do Case (Let bnds e) w ty alts <- idR+     let captures = mkVarSet (bindVars bnds) `intersectVarSet` delVarSet (unionVarSets $ map freeVarsAlt alts) w+     if isEmptyVarSet captures+       then return $ Let bnds (Case e w ty alts)+       else caseAllR (alphaLetVarsR $ varSetElems captures) idR idR (const idR) >>> letFloatCaseR++-- | @cast (let bnds in e) co@ ==> @let bnds in cast e co@+letFloatCastR :: MonadCatch m => Rewrite c m CoreExpr+letFloatCastR = prefixFailMsg "Let floating from Cast failed: " $+                withPatFailMsg (wrongExprForm "Cast (Let bnds e) co") $+  do Cast (Let bnds e) co <- idR+     return $ Let bnds (Cast e co)++-- | Float a 'Let' through an expression, whatever the context.+letFloatExprR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr+letFloatExprR = setFailMsg "Unsuitable expression for Let floating." $+               letFloatArgR <+ letFloatAppR <+ letFloatLetR <+ letFloatLamR <+ letFloatCaseR <+ letFloatCastR++-- | @'ProgCons' ('NonRec' v ('Let' bds e)) p@ ==> @'ProgCons' bds ('ProgCons' ('NonRec' v e) p)@+letFloatTopR :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreProg+letFloatTopR = prefixFailMsg "Let floating to top level failed: " $+               withPatFailMsg (wrongExprForm "NonRec v (Let bds e) `ProgCons` p") $+               do ProgCons (NonRec v (Let bds e)) p <- idR+                  let bs = bindVars bds+                  guardMsg (all isId bs) "type and coercion bindings are not allowed at the top level."+                  let vs = intersectVarSet (mkVarSet bs) (freeVarsProg p)+                  if isEmptyVarSet vs+                    then return $ ProgCons bds (ProgCons (NonRec v e) p)+                    else consNonRecAllR idR (alphaLetVarsR $ varSetElems vs) idR >>> letFloatTopR++-------------------------------------------------------------------------------------------++-- | Unfloat a 'Let' if possible.+letUnfloatR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr+letUnfloatR = letUnfloatCaseR <+ letUnfloatAppR <+ letUnfloatLamR++-- | @let v = ev in case s of p -> e@ ==> @case (let v = ev in s) of p -> let v = ev in e@,+--   if @v@ does not shadow a pattern binder in @p@+letUnfloatCaseR :: MonadCatch m => Rewrite c m CoreExpr+letUnfloatCaseR = prefixFailMsg "Let unfloating from case failed: " $+                  withPatFailMsg (wrongExprForm "Let bnds (Case s w ty alts)") $+  do Let bnds (Case s w ty alts) <- idR+     let bs = bindVars bnds+         captured = bs `intersect` (w : concatMap altVars alts)+     guardMsg (null captured) "let bindings would capture case pattern bindings."+     let unbound = mkVarSet bs `intersectVarSet` tyVarsOfType ty+     guardMsg (isEmptyVarSet unbound) "type variables in case signature would become unbound."+     return $ Case (Let bnds s) w ty $ mapAlts (Let bnds) alts++-- | @let v = ev in f a@ ==> @(let v = ev in f) (let v = ev in a)@+letUnfloatAppR :: MonadCatch m => Rewrite c m CoreExpr+letUnfloatAppR = prefixFailMsg "Let unfloating from app failed: " $+                withPatFailMsg (wrongExprForm "Let bnds (App e1 e2)") $+  do Let bnds (App e1 e2) <- idR+     return $ App (Let bnds e1) (Let bnds e2)++-- | @let v = ev in \ x -> e@ ==> @\x -> let v = ev in e@+--   if @v@ does not shadow @x@+letUnfloatLamR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr+letUnfloatLamR = prefixFailMsg "Let unfloating from lambda failed: " $+                withPatFailMsg (wrongExprForm "Let bnds (Lam v e)") $+  do Let bnds (Lam v e) <- idR+     safe <- letT (arr bindVars) lamVarT $ flip notElem+     guardMsg safe "let bindings would capture lambda binding."+     return $ Lam v $ Let bnds e++-------------------------------------------------------------------------------------------++-- | Re-order a sequence of nested non-recursive let bindings.+--   The argument list should contain the let-bound variables, in the desired order.+reorderNonRecLetsR :: MonadCatch m => [TH.Name] -> Rewrite c m CoreExpr+reorderNonRecLetsR nms = prefixFailMsg "Reorder lets failed: " $+                 do guardMsg (notNull nms) "no names given."+                    guardMsg (nodups nms) "duplicate names given."+                    e <- idR+                    (ves,x) <- setFailMsg "insufficient non-recursive lets." $ takeNonRecLets (length nms) e+                    guardMsg (noneFreeIn ves) "some of the bound variables appear in the right-hand-sides."+                    e' <- mkNonRecLets `liftM` mapM (lookupName ves) nms `ap` return x+                    guardMsg (not $ exprSyntaxEq e e') "bindings already in specified order."+                    return e'+  where+    takeNonRecLets :: Monad m => Int -> CoreExpr -> m ([(Var,CoreExpr)],CoreExpr)+    takeNonRecLets 0 x                      = return ([],x)+    takeNonRecLets n (Let (NonRec v1 e1) x) = first ((v1,e1):) `liftM` takeNonRecLets (n-1) x+    takeNonRecLets _ _                      = fail "insufficient non-recursive lets."++    noneFreeIn :: [(Var,CoreExpr)] -> Bool+    noneFreeIn ves = let (vs,es) = unzip ves+                      in all (`notElemVarSet` unionVarSets (map freeVarsExpr es)) vs++    lookupName :: Monad m => [(Var,CoreExpr)] -> TH.Name -> m (Var,CoreExpr)+    lookupName ves nm = let n = show nm+                         in case filter (cmpString2Var n . fst) ves of+                              []   -> fail $ "name " ++ n ++ " not matched."+                              [ve] -> return ve+                              _    -> fail $ "multiple matches for " ++ n ++ "."++    mkNonRecLets :: [(Var,CoreExpr)] -> CoreExpr -> CoreExpr+    mkNonRecLets []          x  = x+    mkNonRecLets ((v,e):ves) x  = Let (NonRec v e) (mkNonRecLets ves x)++-------------------------------------------------------------------------------------------++-- | Combine nested non-recursive lets into case of a tuple.+--   E.g. let {v1 = e1 ; v2 = e2 ; v3 = e3} in body ==> case (e1,e2,e3) of {(v1,v2,v3) -> body}+letTupleR :: String -> Rewrite c HermitM CoreExpr+letTupleR nm = prefixFailMsg "Let-tuple failed: " $+      do (bnds, body) <- arr collectLets+         let numBnds = length bnds+         guardMsg (numBnds > 1) "at least two non-recursive let bindings of identifiers required."++         let (vs, rhss) = unzip bnds++         -- check if tupling the bindings would cause unbound variables+         let frees  = map freeVarsExpr (drop 1 rhss)+             used   = unionVarSets $ zipWith intersectVarSet (map (mkVarSet . (`take` vs)) [1..]) frees+         if isEmptyVarSet used+           then let rhs = mkCoreTup rhss+                in constT $ do wild <- newIdH nm (exprType rhs)+                               return $ mkSmallTupleCase vs body wild rhs++           else fail $ "the following bound variables are used in subsequent bindings: " ++ showVarSet used++  where+    -- we only collect identifiers (not type or coercion vars) because we intend to case on them.+    collectLets :: CoreExpr -> ([(Id, CoreExpr)],CoreExpr)+    collectLets (Let (NonRec v e) body) | isId v = first ((v,e):) (collectLets body)+    collectLets expr                             = ([],expr)++-------------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Navigation.hs view
@@ -0,0 +1,248 @@+{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}++module HERMIT.Dictionary.Navigation+       ( -- * Navigation+         externals+       , occurrenceOfT+       , bindingOfT+       , bindingGroupOfT+       , rhsOfT+       , parentOfT+       , occurrenceOfTargetsT+       , bindingOfTargetsT+       , bindingGroupOfTargetsT+       , rhsOfTargetsT+       , Considerable(..)+       , considerables+       , considerConstructT+       , nthArgPath+       )+where++import Data.Monoid (mempty)++import Control.Arrow++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC++import HERMIT.Dictionary.Navigation.Crumbs++import qualified Language.Haskell.TH as TH++---------------------------------------------------------------------------------------++-- | 'External's involving navigating to named entities.+externals :: [External]+externals = crumbExternals ++ map (.+ Navigation)+            [ external "rhs-of" (rhsOfT . cmpTHName2Var :: TH.Name -> TranslateH Core LocalPathH)+                [ "Find the path to the RHS of the binding of the named variable." ]+            , external "binding-group-of" (bindingGroupOfT . cmpTHName2Var :: TH.Name -> TranslateH CoreTC LocalPathH)+                [ "Find the path to the binding group of the named variable." ]+            , external "binding-of" (bindingOfT . cmpTHName2Var :: TH.Name -> TranslateH CoreTC LocalPathH)+                [ "Find the path to the binding of the named variable." ]+            , external "occurrence-of" (occurrenceOfT . cmpTHName2Var :: TH.Name -> TranslateH CoreTC LocalPathH)+                [ "Find the path to the first occurrence of the named variable." ]++            , external "consider" (bindingOfT . cmpTHName2Var :: TH.Name -> TranslateH CoreTC LocalPathH)+                [ "consider '<v> focuses on the definition of <v>" ] .+ Deprecated .+ TODO++            , external "consider" (considerConstruct :: String -> TranslateH Core LocalPathH)+                [ "consider <c> focuses on the first construct <c>.",+                  recognizedConsiderables]+            , external "arg" (promoteExprT . nthArgPath :: Int -> TranslateH Core LocalPathH)+                [ "arg n focuses on the (n-1)th argument of a nested application." ]++            , external "parent-of" (parentOfT :: TranslateH Core LocalPathH -> TranslateH Core LocalPathH)+                [ "Focus on the parent of another focal point." ]+            , external "parent-of" (parentOfT :: TranslateH CoreTC LocalPathH -> TranslateH CoreTC LocalPathH)+                [ "Focus on the parent of another focal point." ]+            ]++---------------------------------------------------------------------------------------++-- | Discard the last crumb of a non-empty 'LocalPathH'.+parentOfT :: MonadCatch m => Translate c m g LocalPathH -> Translate c m g LocalPathH+parentOfT t = withPatFailMsg "Path points to origin, there is no parent." $+              do SnocPath (_:p) <- t+                 return (SnocPath p)++-----------------------------------------------------------------------++-- | Find the path to the RHS of a binding.+rhsOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m Core LocalPathH+rhsOfT p = prefixFailMsg ("rhs-of failed: ") $+           do lp <- onePathToT (arr $ bindingOf p . inject)+              case lastCrumb lp of+                Just crumb -> case crumb of+                                Rec_Def _     -> return (lp @@ Def_RHS)+                                Let_Bind      -> return (lp @@ NonRec_RHS)+                                ProgCons_Head -> return (lp @@ NonRec_RHS)+                                _             -> fail "does not have a RHS."+                Nothing -> defOrNonRecT successT lastCrumbT (\ () cr -> mempty @@ cr)++-- | Find the path to the binding group of a variable.+bindingGroupOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m CoreTC LocalPathH+bindingGroupOfT p = prefixFailMsg ("binding-group-of failed: ") $+                    oneNonEmptyPathToT (promoteBindT $ arr $ bindingGroupOf p)++-- | Find the path to the binding of a variable.+bindingOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m CoreTC LocalPathH+bindingOfT p = prefixFailMsg ("binding-of failed: ") $+               oneNonEmptyPathToT (arr $ bindingOf p)++-- | Find the path to the first occurrence occurrence of a variable.+occurrenceOfT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => (Var -> Bool) -> Translate c m CoreTC LocalPathH+occurrenceOfT p = prefixFailMsg ("occurrence-of failed: ") $+                  oneNonEmptyPathToT (arr $ occurrenceOf p)++-----------------------------------------------------------------------++bindingGroupOf :: (Var -> Bool) -> CoreBind -> Bool+bindingGroupOf p = any p . bindVars++-----------------------------------------------------------------------++bindingOf :: (Var -> Bool) -> CoreTC -> Bool+bindingOf p = any p . varSetElems . binders++binders :: CoreTC -> VarSet+binders (Core core)              = bindersCore core+binders (TyCo (TypeCore ty))     = binderType ty+binders (TyCo (CoercionCore co)) = binderCoercion co++bindersCore :: Core -> VarSet+bindersCore (BindCore bnd)  = binderBind bnd+bindersCore (DefCore def)   = binderDef def+bindersCore (ExprCore expr) = binderExpr expr+bindersCore (AltCore alt)   = mkVarSet (altVars alt)+bindersCore _               = emptyVarSet++binderBind :: CoreBind -> VarSet+binderBind (NonRec v _) = unitVarSet v+binderBind _            = emptyVarSet++binderDef :: CoreDef -> VarSet+binderDef = unitVarSet . defId++binderExpr :: CoreExpr -> VarSet+binderExpr (Lam v _)      = unitVarSet v+binderExpr (Case _ w _ _) = unitVarSet w+binderExpr _              = emptyVarSet++binderType :: Type -> VarSet+binderType (ForAllTy v _) = unitVarSet v+binderType _              = emptyVarSet++binderCoercion :: Coercion -> VarSet+binderCoercion (ForAllCo v _) = unitVarSet v+binderCoercion _              = emptyVarSet++-----------------------------------------------------------------------++occurrenceOf :: (Var -> Bool) -> CoreTC -> Bool+occurrenceOf p = maybe False p . varOccurrence++varOccurrence :: CoreTC -> Maybe Var+varOccurrence (Core (ExprCore e))      = varOccurrenceExpr e+varOccurrence (TyCo (TypeCore ty))     = varOccurrenceType ty+varOccurrence (TyCo (CoercionCore co)) = varOccurrenceCoercion co+varOccurrence _                        = Nothing++varOccurrenceExpr :: CoreExpr -> Maybe Var+varOccurrenceExpr (Var v)       = Just v+varOccurrenceExpr _             = Nothing++varOccurrenceType :: Type -> Maybe Var+varOccurrenceType (TyVarTy v) = Just v+varOccurrenceType _           = Nothing++varOccurrenceCoercion :: Coercion -> Maybe Var+varOccurrenceCoercion (CoVarCo v) = Just v+varOccurrenceCoercion _           = Nothing++-----------------------------------------------------------------------++-- | Find all possible targets of 'occurrenceOfT'.+occurrenceOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet+occurrenceOfTargetsT = allT $ crushbuT (arr varOccurrence >>> projectT >>^ unitVarSet)++-- | Find all possible targets of 'bindingOfT'.+bindingOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet+bindingOfTargetsT = allT $ crushbuT (arr binders)++-- | Find all possible targets of 'bindingGroupOfT'.+bindingGroupOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet+bindingGroupOfTargetsT = allT $ crushbuT (promoteBindT $ arr (mkVarSet . bindVars))++-- | Find all possible targets of 'rhsOfT'.+rhsOfTargetsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreTC VarSet+rhsOfTargetsT = crushbuT (promoteBindT (arr binderBind) <+ promoteDefT (arr binderDef))++-----------------------------------------------------------------------++-- | Language constructs that can be zoomed to.+data Considerable = Binding | Definition | CaseAlt | Variable | Literal | Application | Lambda | LetExpr | CaseOf | Casty | Ticky | TypeExpr | CoercionExpr++recognizedConsiderables :: String+recognizedConsiderables = "Recognized constructs are: " ++ show (map fst considerables)++-- | Lookup table for constructs that can be considered; the keys are the arguments the user can give to the \"consider\" command.+considerables ::  [(String,Considerable)]+considerables =   [ ("bind",Binding)+                  , ("def",Definition)+                  , ("alt",CaseAlt)+                  , ("var",Variable)+                  , ("lit",Literal)+                  , ("app",Application)+                  , ("lam",Lambda)+                  , ("let",LetExpr)+                  , ("case",CaseOf)+                  , ("cast",Casty)+                  , ("tick",Ticky)+                  , ("type",TypeExpr)+                  , ("coerce",CoercionExpr)+                  ]++considerConstruct :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => String -> Translate c m Core LocalPathH+considerConstruct str = case string2considerable str of+                          Nothing -> fail $ "Unrecognized construct \"" ++ str ++ "\". " ++ recognizedConsiderables ++ ".  Or did you mean \"consider '" ++ str ++ "\"?"+                          Just c  -> considerConstructT c++-- | Find the path to the first matching construct.+considerConstructT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => Considerable -> Translate c m Core LocalPathH+considerConstructT con = oneNonEmptyPathToT (arr $ underConsideration con)++string2considerable :: String -> Maybe Considerable+string2considerable = flip lookup considerables++underConsideration :: Considerable -> Core -> Bool+underConsideration Binding      (BindCore _)               = True+underConsideration Definition   (BindCore (NonRec _ _))    = True+underConsideration Definition   (DefCore _)                = True+underConsideration CaseAlt      (AltCore _)                = True+underConsideration Variable     (ExprCore (Var _))         = True+underConsideration Literal      (ExprCore (Lit _))         = True+underConsideration Application  (ExprCore (App _ _))       = True+underConsideration Lambda       (ExprCore (Lam _ _))       = True+underConsideration LetExpr      (ExprCore (Let _ _))       = True+underConsideration CaseOf       (ExprCore (Case _ _ _ _))  = True+underConsideration Casty        (ExprCore (Cast _ _))      = True+underConsideration Ticky        (ExprCore (Tick _ _))      = True+underConsideration TypeExpr     (ExprCore (Type _))        = True+underConsideration CoercionExpr (ExprCore (Coercion _))    = True+underConsideration _            _                          = False++---------------------------------------------------------------------------------------++-- | Construct a path to the (n-1)th argument in a nested sequence of 'App's.+nthArgPath :: Monad m => Int -> Translate c m CoreExpr LocalPathH+nthArgPath n = contextfreeT $ \ e -> let funCrumbs = appCount e - 1 - n+                                      in if funCrumbs < 0+                                          then fail ("Argument " ++ show n ++ " does not exist.")+                                          else return (SnocPath (replicate funCrumbs App_Fun) @@ App_Arg)++---------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Navigation/Crumbs.hs view
@@ -0,0 +1,100 @@+module HERMIT.Dictionary.Navigation.Crumbs+       ( -- * Navigating Using Crumbs+         crumbExternals+       )+where++import HERMIT.Core+import HERMIT.External++---------------------------------------------------------------------------------------++-- | 'External's for individual 'Crumb's.+crumbExternals :: [External]+crumbExternals = map (.+ Navigation)+            [+              external "prog" ModGuts_Prog+                [ "Descend into the program within a module." ]+            , external "prog-head" ProgCons_Head+                [ "Descend into the first binding group in a program." ]+            , external "prog-tail" ProgCons_Tail+                [ "Descend into the tail of the program." ]+            , external "nonrec-rhs" NonRec_RHS+                [ "Descend into the right-hand side of a non-recursive binding." ]+            , external "rec-def" Rec_Def+                [ "Descend into the (n-1)th definition in a recursive binding group." ]+            , external "def-rhs" Def_RHS+                [ "Descend into the right-hand side of a recursive definition." ]+            , external "app-fun" App_Fun+                [ "Descend into the function in an application." ]+            , external "app-arg" App_Arg+                [ "Descend into the argument in an application." ]+            , external "lam-body" Lam_Body+                [ "Descend into the body of a lambda." ]+            , external "let-bind" Let_Bind+                [ "Descend into the binding group of a let expression." ]+            , external "let-body" Let_Body+                [ "Descend into the body of a let expression." ]+            , external "case-expr" Case_Scrutinee+                [ "Descend into the scrutinised expression in a case expression." ]+            , external "case-type" Case_Type+                [ "Descend into the type of a case expression." ]+            , external "case-alt" Case_Alt+                [ "Descend into the (n-1)th alternative in a case expression." ]+            , external "cast-expr" Cast_Expr+                [ "Descend into the expression in a cast." ]+            , external "cast-co" Cast_Co+                [ "Descend into the coercion in a cast." ]+            , external "tick-expr" Tick_Expr+                [ "Descend into the expression in a tick." ]+            , external "alt-rhs" Alt_RHS+                [ "Descend into the right-hand side of a case alternative." ]+            , external "type" Type_Type+                [ "Descend into the type within a type expression." ]+            , external "coercion" Co_Co+                [ "Descend into the coercion within a coercion expression." ]+            , external "appTy-fun" AppTy_Fun+                [ "Descend into the type function in a type application." ]+            , external "appTy-arg" AppTy_Fun+                [ "Descend into the type argument in a type application." ]+            , external "tyCon-arg" TyConApp_Arg+                [ "Descend into the (n-1)th argument of a type constructor application." ]+            , external "fun-dom" FunTy_Dom+                [ "Descend into the domain of a function type." ]+            , external "fun-cod" FunTy_CoDom+                [ "Descend into the codomain of a function type." ]+            , external "forall-body" ForAllTy_Body+                [ "Descend into the body of a forall type." ]+            , external "refl-type" Refl_Type+                [ "Descend into the (n-1)th argument of a type constructor coercion." ]+            , external "coCon-arg" TyConAppCo_Arg+                [ "Descend into the function of a coercion application." ]+            , external "appCo-fun" AppCo_Fun+                [ "Descend into the coercion function in a coercion application." ]+            , external "appCo-arg" AppCo_Arg+                [ "Descend into the coercion argument in a coercion application." ]+            , external "coForall-body" ForAllCo_Body+                [ "Descend into the body of a forall coercion." ]+            , external "axiom-inst" AxiomInstCo_Arg+                [ "Descend into the (n-1)th argument of a coercion axiom instantiation." ]+            , external "unsafe-left" UnsafeCo_Left+                [ "Descend into the left-hand type of an unsafe coercion." ]+            , external "unsafe-right" UnsafeCo_Right+                [ "Descend into the right-hand type of an unsafe coercion." ]+            , external "sym-co" SymCo_Co+                [ "Descend into the coercion within a symmetric coercion." ]+            , external "trans-left" TransCo_Left+                [ "Descend into the left-hand type of a transitive coercion." ]+            , external "trans-right" TransCo_Right+                [ "Descend into the right-hand type of a transitive coercion." ]+            , external "nth-co" NthCo_Co+                [ "Descend into the coercion within an nth projection coercion." ]+            , external "inst-co" InstCo_Co+                [ "Descend into the coercion within a coercion instantiation." ]+            , external "inst-type" InstCo_Type+                [ "Descend into the type within a coercion instantiation." ]+            , external "lr-co" LRCo_Co+                [ "Descend into the coercion within a left/right projection coercion." ]+            ]++---------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/New.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE FlexibleContexts, MultiWayIf #-}+module HERMIT.Dictionary.New where++import Control.Arrow++import HERMIT.Context+import HERMIT.Core+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC+import HERMIT.ParserCore++import qualified Language.Haskell.TH as TH++externals ::  [External]+externals = map ((.+ Experiment) . (.+ TODO))+         [ external "var" (promoteExprT . isVar :: TH.Name -> TranslateH Core ())+                [ "var '<v> returns successfully for variable v, and fails otherwise.",+                  "Useful in combination with \"when\", as in: when (var v) r" ] .+ Predicate+         , external "prog-nonrec-intro" ((\ nm core -> promoteProgR $ progNonRecIntroR (show nm) core) :: TH.Name -> CoreString -> RewriteH Core)+                [ "Introduce a new top-level definition."+                , "prog-nonrec-into 'v [| e |]"+                , "prog ==> ProgCons (v = e) prog" ] .+ Introduce .+ Shallow+         , external "let-nonrec-intro" ((\ nm core -> promoteExprR $ letNonRecIntroR (show nm) core) :: TH.Name -> CoreString -> RewriteH Core)+                [ "Introduce a new definition as a non-recursive let binding."+                , "let-nonrec-intro 'v [| e |]"+                , "body ==> let v = e in body" ] .+ Introduce .+ Shallow+         ]++------------------------------------------------------------------------------------------------------++-- TODO:  We might not want to match on TyVars and CoVars here.+-- Probably better to have another predicate that operates on CoreTC, that way it can reach TyVars buried within types.+-- But given the current setup (using Core for most things), changing "var" to operate on CoreTC would make it incompatible with other combinators.+-- I'm not sure how to fix the current setup though.+-- isVar :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Translate c m CoreExpr ()+-- isVar nm = (varT matchName <+ typeT (tyVarT matchName) <+ coercionT (coVarCoT matchName))+--                  >>= guardM+--   where+--     matchName :: Monad m => Translate c m Var Bool+--     matchName = arr (cmpTHName2Var nm)++-- TODO: there might be a better module for this++-- | Test if the current expression is an identifier matching the given name.+isVar :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Translate c m CoreExpr ()+isVar nm = varT (arr $ cmpTHName2Var nm) >>= guardM++------------------------------------------------------------------------------------------------------++-- The types of these can probably be generalised after the Core Parser is generalised.++-- | @prog@ ==> @'ProgCons' (v = e) prog@+progNonRecIntroR :: String -> CoreString -> RewriteH CoreProg+progNonRecIntroR nm expr =+  do e <- parseCoreExprT expr+     guardMsg (not $ isTyCoArg e) "Top-level type or coercion definitions are prohibited."+     -- TODO: if e is not type-correct, then exprType will crash.+     --       Proposal: parseCore should check that its result is (locally) well-typed+     contextfreeT $ \ prog -> do i <- newIdH nm (exprType e)+                                 return $ ProgCons (NonRec i e) prog++-- | @body@ ==> @let v = e in body@+letNonRecIntroR :: String -> CoreString -> RewriteH CoreExpr+letNonRecIntroR nm expr =+  do e <- parseCoreExprT expr+     -- TODO: if e is not type-correct, then exprTypeOrKind will crash.+     --       Proposal: parseCore should check that its result is (locally) well-typed+     contextfreeT $ \ body -> do let tyk = exprKindOrType e+                                 v <- if | isTypeArg e  -> newTyVarH nm tyk+                                         | isCoArg e    -> newCoVarH nm tyk+                                         | otherwise    -> newIdH nm tyk+                                 return $ Let (NonRec v e) body++------------------------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Query.hs view
@@ -0,0 +1,178 @@+{-# LANGUAGE CPP, LambdaCase, FlexibleContexts #-}++module HERMIT.Dictionary.Query+  ( -- * Queries and Predicates+    externals+  , infoT+  , compareCoreAtT+  , compareBoundIdsT+  )+where++import Control.Arrow++import Data.List (intercalate)++import HERMIT.Context+import HERMIT.Core+import HERMIT.External+import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad++import HERMIT.Dictionary.AlphaConversion hiding (externals)+import HERMIT.Dictionary.Common+import HERMIT.Dictionary.GHC hiding (externals)+import HERMIT.Dictionary.Inline hiding (externals)++import qualified Language.Haskell.TH as TH++--------------------------------------------------------++-- | Externals that reflect GHC functions, or are derived from GHC functions.+externals :: [External]+externals =+         [ external "info" (infoT :: TranslateH CoreTC String)+                [ "Display information about the current node." ] .+ Query+         , external "compare-bound-ids" (compareBoundIds ::  TH.Name -> TH.Name -> TranslateH CoreTC ())+                [ "Compare the definitions of two in-scope identifiers for alpha equality."] .+ Query .+ Predicate+         , external "compare-core-at" (compareCoreAtT ::  TranslateH Core LocalPathH -> TranslateH Core LocalPathH -> TranslateH Core ())+                [ "Compare the core fragments at the end of the given paths for alpha-equality."] .+ Query .+ Predicate+         ]++--------------------------------------------------------++infoT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, ReadBindings c, BoundVars c, HasDynFlags m, MonadCatch m) => Translate c m CoreTC String+infoT =+  do crumbs <- childrenT+     fvs    <- arr freeVarsCoreTC+     translate $ \ c coreTC ->+       do dynFlags <- getDynFlags+          let node     =   "Node:        " ++ coreTCNode coreTC+              con      =   "Constructor: " ++ coreTCConstructor coreTC+              pa       =   "Path:     " ++ showCrumbs (snocPathToPath $ absPath c)+              children =   "Children: " ++ showCrumbs crumbs+              bds      =   "Local bindings in scope: " ++ showVarSet (boundVars c)+              freevars = [ "Free local identifiers:  " ++ showVarSet (filterVarSet isLocalId fvs)+                         , "Free global identifiers: " ++ showVarSet (filterVarSet isGlobalId fvs)+                         , "Free type variables:     " ++ showVarSet (filterVarSet isTyVar fvs)+                         , "Free coercion variables: " ++ showVarSet (filterVarSet isCoVar fvs)+                         ]+              typeId   = case coreTC of+                             Core (ExprCore e)      -> let tyK = exprKindOrType e+                                                        in [(if isKind tyK then "Kind:        " else "Type:        ") ++ showPpr dynFlags tyK] +++                                                           case e of+                                                             Var i -> [ ""+                                                                      , "Identifier arity:         " ++ show (arityOf c i)+                                                                      , "Identifier binding depth: " ++ runKureM show id (lookupHermitBindingDepth i c) ]+                                                             _     -> []+                             TyCo (TypeCore ty)     -> ["Kind: " ++ showPpr dynFlags (typeKind ty)]+                             TyCo (CoercionCore co) -> ["Kind: " ++ showPpr dynFlags (coercionKind co) ]+                             _                      -> []++          return $ intercalate "\n" ([node,con] ++ typeId ++ ["",pa,children,""] ++ freevars ++ [bds])++-- showIdInfo :: DynFlags -> Id -> String+-- showIdInfo dynFlags v = showSDoc dynFlags $ ppIdInfo v $ idInfo v++--------------------------------------------------------++coreTCNode :: CoreTC -> String+coreTCNode (Core core)           = coreNode core+coreTCNode (TyCo TypeCore{})     = "Type"+coreTCNode (TyCo CoercionCore{}) = "Coercion"++coreNode :: Core -> String+coreNode (GutsCore _)  = "Module"+coreNode (ProgCore _)  = "Program"+coreNode (BindCore _)  = "Binding Group"+coreNode (DefCore _)   = "Recursive Definition"+coreNode (ExprCore _)  = "Expression"+coreNode (AltCore _)   = "Case Alternative"++coreTCConstructor :: CoreTC -> String+coreTCConstructor = \case+                       Core core              -> coreConstructor core+                       TyCo (TypeCore ty)     -> typeConstructor ty+                       TyCo (CoercionCore co) -> coercionConstructor co++coreConstructor :: Core -> String+coreConstructor (GutsCore _)     = "ModGuts"+coreConstructor (ProgCore prog)  = case prog of+                                     ProgNil      -> "ProgNil"+                                     ProgCons _ _ -> "ProgCons"+coreConstructor (BindCore bnd)   = case bnd of+                                     Rec _      -> "Rec"+                                     NonRec _ _ -> "NonRec"+coreConstructor (DefCore _)      = "Def"+coreConstructor (AltCore _)      = "(,,)"+coreConstructor (ExprCore expr)  = case expr of+                                     Var _        -> "Var"+                                     Type _       -> "Type"+                                     Lit _        -> "Lit"+                                     App _ _      -> "App"+                                     Lam _ _      -> "Lam"+                                     Let _ _      -> "Let"+                                     Case _ _ _ _ -> "Case"+                                     Cast _ _     -> "Cast"+                                     Tick _ _     -> "Tick"+                                     Coercion _   -> "Coercion"++typeConstructor :: Type -> String+typeConstructor = \case+                     TyVarTy{}    -> "TyVarTy"+                     AppTy{}      -> "AppTy"+                     TyConApp{}   -> "TyConApp"+                     FunTy{}      -> "FunTy"+                     ForAllTy{}   -> "ForAllTy"+                     LitTy{}      -> "LitTy"++coercionConstructor :: Coercion -> String+coercionConstructor = \case+                         Refl{}        -> "Refl"+                         TyConAppCo{}  -> "TyConAppCo"+                         AppCo{}       -> "AppCo"+                         ForAllCo{}    -> "ForAllCo"+                         CoVarCo{}     -> "CoVarCo"+                         AxiomInstCo{} -> "AxiomInstCo"+                         SymCo{}       -> "SymCo"+                         TransCo{}     -> "TransCo"+                         NthCo{}       -> "NthCo"+                         InstCo{}      -> "InstCo"+#if __GLASGOW_HASKELL__ > 706+                         LRCo{}        -> "LRCo"+                         SubCo{}       -> "SubCo"+                         UnivCo{}      -> "UnivCo"+#else+                         UnsafeCo{}    -> "UnsafeCo"+#endif++--------------------------------------------------------++-- | Compare the core fragments at the end of the specified 'LocalPathH's.+compareCoreAtT :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, ReadPath c Crumb, MonadCatch m) => Translate c m Core LocalPathH -> Translate c m Core LocalPathH -> Translate c m Core ()+compareCoreAtT p1T p2T =+  do p1 <- p1T+     p2 <- p2T+     core1 <- localPathT p1 idR+     core2 <- localPathT p2 idR+     guardMsg (core1 `coreAlphaEq` core2) "core fragments are not alpha-equivalent."++-- | Compare the definitions of two identifiers for alpha-equality.+compareBoundIdsT :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Id -> Id -> Translate c HermitM x ()+compareBoundIdsT i1 i2 =+  do e1 <-                       fst ^<< getUnfoldingT AllBinders <<< return i1+     e2 <- replaceVarR i2 i1 <<< fst ^<< getUnfoldingT AllBinders <<< return i2+     -- recursive definitions wouldn't be alpha-equivalent without replacing the identifier+     guardMsg (e1 `exprAlphaEq` e2) "bindings are not alpha-equivalent."++-- | Compare the definitions of the two named identifiers for alpha-equality.+compareBoundIds :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, HasGlobalRdrEnv c) => TH.Name -> TH.Name -> Translate c HermitM x ()+compareBoundIds nm1 nm2 = do i1 <- findIdT nm1+                             i2 <- findIdT nm2+                             compareBoundIdsT i1 i2++-- TODO: generalise compareBoundIds to comparBoundVars.+--       this will require generalising the underlying functions++--------------------------------------------------------
+ src/HERMIT/Dictionary/Reasoning.hs view
@@ -0,0 +1,109 @@+{-# LANGUAGE ScopedTypeVariables #-}++module HERMIT.Dictionary.Reasoning+  ( -- * Equational Reasoning+    externals+  , verifyEqualityLeftToRightT+  , verifyEqualityCommonTargetT+  , verifyIsomorphismT+  , verifyRetractionT+  , retractionBR+  )+where++import Control.Applicative+import Control.Arrow++import HERMIT.Core+import HERMIT.External+import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.ParserCore+import HERMIT.Utilities++import HERMIT.Dictionary.Common++------------------------------------------------------------------------------++externals :: [External]+externals =+  [ external "retraction" ((\ f g r -> promoteExprBiR $ retraction (Just r) f g) :: CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+        [ "Given f :: X -> Y and g :: Y -> X, and a proof that f (g y) ==> y, then"+        , "f (g y) <==> y."+        ] .+ Shallow+  , external "retraction-unsafe" ((\ f g -> promoteExprBiR $ retraction Nothing f g) :: CoreString -> CoreString -> BiRewriteH Core)+        [ "Given f :: X -> Y and g :: Y -> X, then"+        , "f (g y) <==> y."+        , "Note that the precondition (f (g y) == y) is expected to hold."+        ] .+ Shallow .+ PreCondition+  ]++------------------------------------------------------------------------------++-- | Given two expressions, and a rewrite from the former to the latter, verify that rewrite.+verifyEqualityLeftToRightT :: MonadCatch m => CoreExpr -> CoreExpr -> Rewrite c m CoreExpr -> Translate c m a ()+verifyEqualityLeftToRightT sourceExpr targetExpr r =+  prefixFailMsg "equality verification failed: " $+  do resultExpr <- r <<< return sourceExpr+     guardMsg (exprAlphaEq targetExpr resultExpr) "result of running proof on lhs of equality does not match rhs of equality."++-- | Given two expressions, and a rewrite from the former to the latter, verify that rewrite.+verifyEqualityCommonTargetT :: MonadCatch m => CoreExpr -> CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Translate c m a ()+verifyEqualityCommonTargetT lhs rhs lhsR rhsR =+  prefixFailMsg "equality verification failed: " $+  do lhsResult <- lhsR <<< return lhs+     rhsResult <- rhsR <<< return rhs+     guardMsg (exprAlphaEq lhsResult rhsResult) "results of running proofs on both sides of equality do not match."++------------------------------------------------------------------------------++-- Note: We use global Ids for verification to avoid out-of-scope errors.++-- | Given f :: X -> Y and g :: Y -> X, verify that f (g y) ==> y and g (f x) ==> x.+verifyIsomorphismT :: CoreExpr -> CoreExpr -> Rewrite c HermitM CoreExpr -> Rewrite c HermitM CoreExpr -> Translate c HermitM a ()+verifyIsomorphismT f g fgR gfR = prefixFailMsg "Isomorphism verification failed: " $+   do (tyX, tyY) <- funsWithInverseTypes f g+      x          <- constT (newGlobalIdH "x" tyX)+      y          <- constT (newGlobalIdH "y" tyY)+      verifyEqualityLeftToRightT (App f (App g (Var y))) (Var y) fgR+      verifyEqualityLeftToRightT (App g (App f (Var x))) (Var x) gfR++-- | Given f :: X -> Y and g :: Y -> X, verify that f (g y) ==> y.+verifyRetractionT :: CoreExpr -> CoreExpr -> Rewrite c HermitM CoreExpr -> Translate c HermitM a ()+verifyRetractionT f g r = prefixFailMsg "Retraction verification failed: " $+   do (_tyX, tyY) <- funsWithInverseTypes f g+      y           <- constT (newGlobalIdH "y" tyY)+      let lhs = App f (App g (Var y))+          rhs = Var y+      verifyEqualityLeftToRightT lhs rhs r++------------------------------------------------------------------------------++-- | Given f :: X -> Y and g :: Y -> X, and a proof that f (g y) ==> y, then f (g y) <==> y.+retractionBR :: forall c. Maybe (Rewrite c HermitM CoreExpr) -> CoreExpr -> CoreExpr -> BiRewrite c HermitM CoreExpr+retractionBR mr f g = beforeBiR+                         (prefixFailMsg "Retraction failed: " $+                          do whenJust (verifyRetractionT f g) mr+                             y        <- idR+                             (_, tyY) <- funsWithInverseTypes f g+                             guardMsg (exprKindOrType y `typeAlphaEq` tyY) "type of expression does not match given retraction components."+                             return y+                         )+                         (\ y -> bidirectional+                                   retractionL+                                   (return $ App f (App g y))+                         )+  where+    retractionL :: Rewrite c HermitM CoreExpr+    retractionL =  prefixFailMsg "Retraction failed: " $+                   withPatFailMsg (wrongExprForm "App f (App g y)") $+      do App f' (App g' y) <- idR+         guardMsg (exprAlphaEq f f' && exprAlphaEq g g') "given retraction components do not match current expression."+         return y++-- | Given @f :: X -> Y@ and @g :: Y -> X@, and a proof that @f (g y)@ ==> @y@, then @f (g y)@ <==> @y@.+retraction :: Maybe (RewriteH Core) -> CoreString -> CoreString -> BiRewriteH CoreExpr+retraction mr = parse2beforeBiR (retractionBR (extractR <$> mr))++------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Undefined.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE FlexibleContexts #-}+module HERMIT.Dictionary.Undefined+    ( -- * Working with Undefined Values+      -- | Note that many of these operations require 'GHC.Err.undefined' to be explicitly imported if it is not used in the source file.+      externals+    , verifyStrictT+    , mkUndefinedValT+    , isUndefinedValT+    , replaceWithUndefinedR+    , errorToUndefinedR+    , undefinedExprR+    , undefinedAppR+    , undefinedLamR+    , undefinedLetR+    , undefinedCaseScrutineeR+    , undefinedCaseAltsR+    , undefinedCaseR+    , undefinedCastR+    , undefinedTickR+    )+where++import Data.Monoid++import HERMIT.Context+import HERMIT.Core+import HERMIT.Kure+import HERMIT.GHC hiding ((<>))+import HERMIT.External++import HERMIT.Dictionary.Common+import HERMIT.Dictionary.Reasoning hiding (externals)++import qualified Language.Haskell.TH as TH++------------------------------------------------------------------------++externals :: [External]+externals = map (.+ Unsafe)+    [ external "replace-with-undefined" (promoteExprR replaceWithUndefinedR :: RewriteH Core)+        [ "Set the current expression to \"undefined\"."+        ] .+ Shallow .+ Context .+ Unsafe+    , external "error-to-undefined" (promoteExprR errorToUndefinedR :: RewriteH Core)+        [ "error ty string  ==>  undefined ty"+        ] .+ Shallow .+ Context+    , external "is-undefined-val" (promoteExprT isUndefinedValT :: TranslateH Core ())+        [ "Succeed if the current expression is an undefined value."+        ] .+ Shallow .+ Context .+ Predicate+    , external "undefined-expr" (promoteExprR undefinedExprR :: RewriteH Core)+        [ "undefined-app <+ undefined-lam <+ undefined-let <+ undefined-cast <+ undefined-tick <+ undefined-case"+        ] .+ Eval .+ Shallow .+ Context+    , external "undefined-app" (promoteExprR undefinedAppR :: RewriteH Core)+        [ "(undefined ty1) e  ==>  undefined ty2"+        ] .+ Eval .+ Shallow .+ Context+    , external "undefined-lam" (promoteExprR undefinedLamR :: RewriteH Core)+        [ "(\\ v -> undefined ty1)  ==>  undefined ty2   (where v is not a 'TyVar')"+        ] .+ Eval .+ Shallow .+ Context+    , external "undefined-let" (promoteExprR undefinedLetR :: RewriteH Core)+        [ "let bds in (undefined ty)  ==>  undefined ty"+        ] .+ Eval .+ Shallow .+ Context+    , external "undefined-case" (promoteExprR undefinedCaseR :: RewriteH Core)+        [ "case (undefined ty) of alts  ==>  undefined ty"+        , "OR"+        , "case e of {pat_1 -> undefined ty ; pat_2 -> undefined ty ; ... ; pat_n -> undefined ty} ==> undefined ty"+        ] .+ Eval .+ Shallow .+ Context+    , external "undefined-cast" (promoteExprR undefinedCastR :: RewriteH Core)+        [ "Cast (undefined ty1) co  ==>  undefined ty2"+        ] .+ Eval .+ Shallow .+ Context+    , external "undefined-tick" (promoteExprR undefinedTickR :: RewriteH Core)+        [ "Tick tick (undefined ty1)  ==>  undefined ty1"+        ] .+ Eval .+ Shallow .+ Context+    ]++------------------------------------------------------------------------++undefinedLocation :: String+undefinedLocation = "GHC.Err.undefined"++-- TODO: will crash if 'undefined' is not used (or explicitly imported) in the source file.+findUndefinedIdT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Translate c m a Id+findUndefinedIdT = findIdT (TH.mkName undefinedLocation)++-- | Check if the current expression is an undefined value.+isUndefinedValT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Translate c m CoreExpr ()+isUndefinedValT = prefixFailMsg "not an undefined value: " $+                  withPatFailMsg (wrongExprForm "App (Var undefined) (Type ty)") $+                  do App (Var un) (Type _) <- idR+                     un' <- findUndefinedIdT+                     guardMsg (un == un') ("identifier is not " ++ undefinedLocation)++------------------------------------------------------------------------++errorLocation :: String+errorLocation = "GHC.Err.error"++-- TODO: will crash if 'error' is not used (or explicitly imported) in the source file.+findErrorIdT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Translate c m a Id+findErrorIdT = findIdT (TH.mkName errorLocation)++-- | Check if the current expression is an undefined value.+isErrorValT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Translate c m CoreExpr ()+isErrorValT = prefixFailMsg "not an error value: " $+              withPatFailMsg (wrongExprForm "App (App (Var error) (Type ty)) string") $+              do App (App (Var er) (Type _)) _ <- idR+                 er' <- findErrorIdT+                 guardMsg (er == er') ("identifier is not " ++ errorLocation)++------------------------------------------------------------------------++-- | error ty string ==> undefined ty+errorToUndefinedR :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+errorToUndefinedR = prefixFailMsg "error-to-undefined failed: " (isErrorValT >> replaceWithUndefinedR)++------------------------------------------------------------------------++-- | Make an undefined value of the given type.+mkUndefinedValT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Type -> Translate c m a CoreExpr+mkUndefinedValT ty =+  do un <- findUndefinedIdT+     return $ App (varToCoreExpr un) (Type ty)++------------------------------------------------------------------------------------------------------++-- | Set the current expression to 'undefined'.+replaceWithUndefinedR :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+replaceWithUndefinedR = contextfreeT exprTypeM >>= mkUndefinedValT++------------------------------------------------------------------------------------------------------++-- | undefinedExprR = undefinedAppR <+ undefinedLamR <+ undefinedLetR <+ undefinedCastR <+ undefinedTickR <+ undefinedCaseR+undefinedExprR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedExprR = setFailMsg "undefined-expr failed."+                   (undefinedAppR <+ undefinedLamR <+ undefinedLetR <+ undefinedCastR <+ undefinedTickR <+ undefinedCaseR)++------------------------------------------------------------------------------------------------------++-- | @(undefined ty1) e@ ==> @undefined ty2@+undefinedAppR :: (BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedAppR = prefixFailMsg "undefined-app failed: " $+                do appT isUndefinedValT successT (<>)+                   replaceWithUndefinedR++-- | @(\ v -> undefined ty1)@ ==> @undefined ty2@  (where v is not a 'TyVar')+undefinedLamR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedLamR = prefixFailMsg "undefined-lam failed: " $+                do lamT successT isUndefinedValT (<>)+                   replaceWithUndefinedR++-- | let bds in (undefined ty) ==> undefined ty+undefinedLetR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedLetR = prefixFailMsg "undefined-let failed: " $+                do letT successT isUndefinedValT (<>)+                   replaceWithUndefinedR++-- | Cast (undefined ty1) co ==> undefined ty2+undefinedCastR :: (BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedCastR = prefixFailMsg "undefined-cast failed: " $+                do castT isUndefinedValT successT (<>)+                   replaceWithUndefinedR++-- | Tick tick (undefined ty1) ==> undefined ty1+undefinedTickR :: (BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedTickR = prefixFailMsg "undefined-tick failed: " $+                do tickT successT isUndefinedValT (<>)+                   replaceWithUndefinedR++-- | undefinedCaseR = undefinedCaseScrutineeR <+ undefinedCaseAltsR+undefinedCaseR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedCaseR = setFailMsg "undefined-case failed" (undefinedCaseScrutineeR <+ undefinedCaseAltsR)++-- | case (undefined ty) of alts ==> undefined ty+undefinedCaseScrutineeR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedCaseScrutineeR = prefixFailMsg "undefined-case failed: " $+                 do caseT isUndefinedValT successT successT (const successT) (\ _ _ _ _ -> ())+                    replaceWithUndefinedR++-- | case e of {pat_1 -> undefined ty ; pat_2 -> undefined ty ; ... ; pat_n -> undefined ty} ==> undefined ty+undefinedCaseAltsR :: (AddBindings c, BoundVars c, ExtendPath c Crumb, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => Rewrite c m CoreExpr+undefinedCaseAltsR = prefixFailMsg "undefined-case-alts failed: " $+                     do caseAltT successT successT successT (const (successT,const successT,isUndefinedValT)) (\ _ _ _ _ -> ())+                        replaceWithUndefinedR++------------------------------------------------------------------------++-- | Verify that the given rewrite is a proof that the given expression is a strict function.+verifyStrictT :: (BoundVars c, HasGlobalRdrEnv c, MonadCatch m, HasDynFlags m, MonadThings m) => CoreExpr -> Rewrite c m CoreExpr -> Translate c m a ()+verifyStrictT f r = prefixFailMsg "strictness verification failed: " $+  do (argTy, resTy) <- constT (funArgResTypes f)+     undefArg       <- mkUndefinedValT argTy+     rhs            <- mkUndefinedValT resTy+     let lhs = App f undefArg+     verifyEqualityLeftToRightT lhs rhs r++------------------------------------------------------------------------
+ src/HERMIT/Dictionary/Unfold.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE FlexibleContexts, ScopedTypeVariables, TupleSections, LambdaCase #-}+module HERMIT.Dictionary.Unfold+    ( externals+    , cleanupUnfoldR+    , rememberR+    , showStashT+    , unfoldR+    , unfoldPredR+    , unfoldNameR+    , unfoldNamesR+    , unfoldSaturatedR+    , unfoldStashR+    , specializeR+    ) where++import Control.Arrow+import Control.Monad++import qualified Data.Map as Map++import qualified Language.Haskell.TH as TH++import HERMIT.PrettyPrinter.Common (DocH, PrettyH, TranslateDocH(..), PrettyC)++import HERMIT.Dictionary.Common+import HERMIT.Dictionary.GHC (rule,inScope)+import HERMIT.Dictionary.Inline (inlineR)+import HERMIT.Dictionary.Local.Let (letNonRecSubstR)++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.External+import HERMIT.GHC++import Prelude hiding (exp)++import qualified Text.PrettyPrint.MarkedHughesPJ as PP++------------------------------------------------------------------------++externals :: [External]+externals =+    [ external "cleanup-unfold" (promoteExprR cleanupUnfoldR :: RewriteH Core)+        [ "Clean up immediately nested fully-applied lambdas, from the bottom up" ] .+ Deep+    , external "remember" (rememberR :: Label -> RewriteH Core)+        [ "Remember the current binding, allowing it to be folded/unfolded in the future." ] .+ Context+    , external "unfold" (promoteExprR . unfoldStashR :: String -> RewriteH Core)+        [ "Unfold a remembered definition." ] .+ Deep .+ Context+    , external "unfold" (promoteExprR unfoldR :: RewriteH Core)+        [ "In application f x y z, unfold f." ] .+ Deep .+ Context+    , external "unfold" (promoteExprR . unfoldNameR :: TH.Name -> RewriteH Core)+        [ "Inline a definition, and apply the arguments; traditional unfold." ] .+ Deep .+ Context+    , external "unfold" (promoteExprR . unfoldNamesR :: [TH.Name] -> RewriteH Core)+        [ "Unfold a definition if it is named in the list." ] .+ Deep .+ Context+    , external "unfold-saturated" (promoteExprR unfoldSaturatedR :: RewriteH Core)+        [ "Unfold a definition only if the function is fully applied." ] .+ Deep .+ Context+    , external "specialize" (promoteExprR specializeR :: RewriteH Core)+        [ "Specialize an application to its type and coercion arguments." ] .+ Deep .+ Context+    , external "unfold-rule" ((\ nm -> promoteExprR (rule nm >>> cleanupUnfoldR)) :: String -> RewriteH Core)+        [ "Unfold a named GHC rule" ] .+ Deep .+ Context .+ TODO -- TODO: does not work with rules with no arguments+    , external "show-remembered" (TranslateDocH showStashT :: TranslateDocH CoreTC)+        [ "Display all remembered definitions." ]+    ]++------------------------------------------------------------------------++-- | cleanupUnfoldR cleans a unfold operation+--  (for example, an inline or rule application)+-- It is used at the level of the top-redex.+-- Invariant: will not introduce let bindings+cleanupUnfoldR :: (AddBindings c, ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr+cleanupUnfoldR = do+    (f, args) <- callT <+ arr (,[])+    let (vs, body) = collectBinders f+        lenargs = length args+        lenvs = length vs+        comp = compare lenargs lenvs+        body' = case comp of+                    LT -> mkCoreLams (drop lenargs vs) body+                    _  -> body+        bnds = zipWith NonRec vs args+    body'' <- andR (replicate (length bnds) letNonRecSubstR) <<< return (mkCoreLets bnds body')+    return $ case comp of+                GT -> mkCoreApps body'' $ drop lenvs args+                _  -> body''++-- | A more powerful 'inline'. Matches two cases:+--      Var ==> inlines+--      App ==> inlines the head of the function call for the app tree+unfoldR :: forall c. (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+unfoldR = prefixFailMsg "unfold failed: " (go >>> cleanupUnfoldR)+    where go :: Rewrite c HermitM CoreExpr+          go = inlineR <+ appAllR go idR++unfoldPredR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => (Id -> [CoreExpr] -> Bool) -> Rewrite c HermitM CoreExpr+unfoldPredR p = callPredT p >> unfoldR++unfoldNameR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM CoreExpr+unfoldNameR nm = prefixFailMsg ("unfold '" ++ show nm ++ " failed: ") (callNameT nm >> unfoldR)++unfoldNamesR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [TH.Name] -> Rewrite c HermitM CoreExpr+unfoldNamesR []  = fail "unfold-names failed: no names given."+unfoldNamesR nms = setFailMsg "unfold-names failed." $+                   orR (map unfoldNameR nms)++unfoldSaturatedR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+unfoldSaturatedR = callSaturatedT >> unfoldR++specializeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr+specializeR = unfoldPredR (const $ all isTyCoArg)++-- NOTE: Using a Rewrite because of the way the Kernel is set up.+--       This is a temporary hack until we work out the best way to structure the Kernel.++-- | Stash a binding with a name for later use.+-- Allows us to look at past definitions.+rememberR :: Label -> Rewrite c HermitM Core+rememberR label = sideEffectR $ \ _ -> \case+                                          DefCore def           -> saveDef label def+                                          BindCore (NonRec i e) -> saveDef label (Def i e)+                                          _                     -> fail "remember failed: not applied to a binding."++-- | Stash a binding with a name for later use.+-- Allows us to look at past definitions.+-- rememberR :: String -> Translate c m Core ()+-- rememberR label = contextfreeT $ \ core ->+--     case core of+--         DefCore def -> saveDef label def+--         BindCore (NonRec i e) -> saveDef label (Def i e)+--         _           -> fail "remember: not a binding"++-- | Apply a stashed definition (like inline, but looks in stash instead of context).+unfoldStashR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr+unfoldStashR label = setFailMsg "Inlining stashed definition failed: " $+                     withPatFailMsg (wrongExprForm "Var v") $+    do (c, Var v) <- exposeT+       constT $ do Def i rhs <- lookupDef label+                   if idName i == idName v -- TODO: Is there a reason we're not just using equality on Id?+                   then if all (inScope c) $ varSetElems $ freeVarsExpr rhs+                          then return rhs+                          else fail "some free variables in stashed definition are no longer in scope."+                   else fail $ "stashed definition applies to " ++ var2String i ++ " not " ++ var2String v++showStashT :: Injection CoreDef a => PrettyC -> PrettyH a -> Translate c HermitM a DocH+showStashT pctx pp = do+    stash <- constT getStash+    docs <- forM (Map.toList stash) $ \ (l,d) -> do+                dfn <- constT $ apply (extractT pp) pctx d+                return $ PP.text ("[ " ++ l ++ " ]") PP.$+$ dfn PP.$+$ PP.space+    return $ PP.vcat docs
+ src/HERMIT/Dictionary/Unsafe.hs view
@@ -0,0 +1,45 @@+module HERMIT.Dictionary.Unsafe+    ( externals+    , unsafeReplaceR+    , unsafeReplaceStashR+    ) where++import Control.Monad++import HERMIT.Core+import HERMIT.Kure+import HERMIT.GHC+import HERMIT.Monad+import HERMIT.External+import HERMIT.ParserCore++import Prelude hiding (exp)++------------------------------------------------------------------------++externals :: [External]+externals = map (.+ Unsafe)+    [ external "unsafe-replace" (promoteExprR . unsafeReplaceR :: CoreString -> RewriteH Core)+        [ "replace the currently focused expression with a new expression" ]+    , external "unsafe-replace" (promoteExprR . unsafeReplaceStashR :: String -> RewriteH Core)+        [ "replace the currently focused expression with an expression from the stash"+        , "DOES NOT ensure expressions have the same type, or that free variables in the replacement expression are in scope" ]+    ]++------------------------------------------------------------------------++unsafeReplaceR :: CoreString -> RewriteH CoreExpr+unsafeReplaceR core =+    translate $ \ c e -> do+        e' <- parseCore core c+        guardMsg (eqType (exprKindOrType e) (exprKindOrType e')) "expression types differ."+        return e'++unsafeReplaceStashR :: String -> RewriteH CoreExpr+unsafeReplaceStashR label = prefixFailMsg "unsafe-replace failed: " $+    contextfreeT $ \ e -> do+        Def _ rhs <- lookupDef label+        guardMsg (eqType (exprKindOrType e) (exprKindOrType rhs)) "expression types differ."+        return rhs++------------------------------------------------------------------------
+ src/HERMIT/Dictionary/WorkerWrapper/Common.hs view
@@ -0,0 +1,23 @@+module HERMIT.Dictionary.WorkerWrapper.Common where++import HERMIT.Monad+import HERMIT.Kure+import HERMIT.GHC++--------------------------------------------------------------------------------------------------++data WWAssumptionTag = A | B | C deriving (Eq,Ord,Show,Read)+data WWAssumption = WWAssumption WWAssumptionTag (RewriteH CoreExpr)++--------------------------------------------------------------------------------------------------++-- Note: The current approach to WW Fusion is a hack.+-- I'm not sure what the best way to approach this is though.+-- An alternative would be to have a generate command that adds ww-fusion to the dictionary, all preconditions verified in advance.+-- That would have to exist at the Shell level though.++-- This isn't entirely safe, as a malicious the user could define a label with this name.+workLabel :: Label+workLabel = "recursive-definition-of-work-for-use-by-ww-fusion"++--------------------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/WorkerWrapper/Fix.hs view
@@ -0,0 +1,458 @@+module HERMIT.Dictionary.WorkerWrapper.Fix+       ( -- * The Worker/Wrapper Transformation+         -- | Note that many of these operations require 'Data.Function.fix' to be in scope.+         HERMIT.Dictionary.WorkerWrapper.Fix.externals+       , wwFacBR+       , wwSplitR+       , wwSplitStaticArg+       , wwGenerateFusionR+       , wwFusionBR+       , wwAssA+       , wwAssB+       , wwAssC+       )+where++import Control.Applicative+import Control.Arrow++import HERMIT.Core+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC+import HERMIT.Utilities+import HERMIT.ParserCore++import HERMIT.Dictionary.AlphaConversion+import HERMIT.Dictionary.Common+import HERMIT.Dictionary.FixPoint+import HERMIT.Dictionary.Function+import HERMIT.Dictionary.Local+import HERMIT.Dictionary.Navigation+import HERMIT.Dictionary.Reasoning+import HERMIT.Dictionary.Unfold++import HERMIT.Dictionary.WorkerWrapper.Common++import qualified Language.Haskell.TH as TH++--------------------------------------------------------------------------------------------------++-- | Externals for manipulating fixed points, and for the worker/wrapper transformation.+externals ::  [External]+externals =+         [+           external "ww-factorisation" ((\ wrap unwrap assC -> promoteExprBiR $ wwFac (mkWWAssC assC) wrap unwrap)+                                          :: CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Factorisation",+                  "For any \"f :: A -> A\", and given \"wrap :: B -> A\" and \"unwrap :: A -> B\" as arguments,",+                  "and a proof of Assumption C (fix A (\\ a -> wrap (unwrap (f a))) ==> fix A f), then",+                  "fix A f  ==>  wrap (fix B (\\ b -> unwrap (f (wrap b))))"+                ] .+ Introduce .+ Context+         , external "ww-factorisation-unsafe" ((\ wrap unwrap -> promoteExprBiR $ wwFac Nothing wrap unwrap)+                                               :: CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Factorisation",+                  "For any \"f :: A -> A\", and given \"wrap :: B -> A\" and \"unwrap :: A -> B\" as arguments, then",+                  "fix A f  <==>  wrap (fix B (\\ b -> unwrap (f (wrap b))))",+                  "Note: the pre-condition \"fix A (\\ a -> wrap (unwrap (f a))) == fix A f\" is expected to hold."+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-split" ((\ wrap unwrap assC -> promoteDefR $ wwSplit (mkWWAssC assC) wrap unwrap)+                                  :: CoreString -> CoreString -> RewriteH Core -> RewriteH Core)+                [ "Worker/Wrapper Split",+                  "For any \"prog :: A\", and given \"wrap :: B -> A\" and \"unwrap :: A -> B\" as arguments,",+                  "and a proof of Assumption C (fix A (\\ a -> wrap (unwrap (f a))) ==> fix A f), then",+                  "prog = expr  ==>  prog = let f = \\ prog -> expr",+                  "                          in let work = unwrap (f (wrap work))",+                  "                              in wrap work"+                ] .+ Introduce .+ Context+         , external "ww-split-unsafe" ((\ wrap unwrap -> promoteDefR $ wwSplit Nothing wrap unwrap)+                                       :: CoreString -> CoreString -> RewriteH Core)+                [ "Unsafe Worker/Wrapper Split",+                  "For any \"prog :: A\", and given \"wrap :: B -> A\" and \"unwrap :: A -> B\" as arguments, then",+                  "prog = expr  ==>  prog = let f = \\ prog -> expr",+                  "                          in let work = unwrap (f (wrap work))",+                  "                              in wrap work",+                  "Note: the pre-condition \"fix A (wrap . unwrap . f) == fix A f\" is expected to hold."+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-split-static-arg" ((\ n is wrap unwrap assC -> promoteDefR $ wwSplitStaticArg n is (mkWWAssC assC) wrap unwrap)+                                      :: Int -> [Int] -> CoreString -> CoreString -> RewriteH Core -> RewriteH Core)+                [ "Worker/Wrapper Split - Static Argument Variant",+                  "Perform the static argument transformation on the first n arguments, then perform the worker/wrapper split,",+                  "applying the given wrap and unwrap functions to the specified (by index) static arguments before use."+                ] .+ Introduce .+ Context+         , external "ww-split-static-arg-unsafe" ((\ n is wrap unwrap -> promoteDefR $ wwSplitStaticArg n is Nothing wrap unwrap)+                                      :: Int -> [Int] -> CoreString -> CoreString -> RewriteH Core)+                [ "Unsafe Worker/Wrapper Split - Static Argument Variant",+                  "Perform the static argument transformation on the first n arguments, then perform the (unsafe) worker/wrapper split,",+                  "applying the given wrap and unwrap functions to the specified (by index) static arguments before use."+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-assumption-A" ((\ wrap unwrap assA -> promoteExprBiR $ wwA (Just $ extractR assA) wrap unwrap)+                                       :: CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Assumption A",+                  "For a \"wrap :: B -> A\" and an \"unwrap :: A -> B\",",+                  "and given a proof of \"wrap (unwrap a) ==> a\", then",+                  "wrap (unwrap a)  <==>  a"+                ] .+ Introduce .+ Context+         , external "ww-assumption-B" ((\ wrap unwrap f assB -> promoteExprBiR $ wwB (Just $ extractR assB) wrap unwrap f)+                                       :: CoreString -> CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Assumption B",+                  "For a \"wrap :: B -> A\", an \"unwrap :: A -> B\", and an \"f :: A -> A\",",+                  "and given a proof of \"wrap (unwrap (f a)) ==> f a\", then",+                  "wrap (unwrap (f a))  <==>  f a"+                ] .+ Introduce .+ Context+         , external "ww-assumption-C" ((\ wrap unwrap f assC -> promoteExprBiR $ wwC (Just $ extractR assC) wrap unwrap f)+                                       :: CoreString -> CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Assumption C",+                  "For a \"wrap :: B -> A\", an \"unwrap :: A -> B\", and an \"f :: A -> A\",",+                  "and given a proof of \"fix A (\\ a -> wrap (unwrap (f a))) ==> fix A f\", then",+                  "fix A (\\ a -> wrap (unwrap (f a)))  <==>  fix A f"+                ] .+ Introduce .+ Context+         , external "ww-assumption-A-unsafe" ((\ wrap unwrap -> promoteExprBiR $ wwA Nothing wrap unwrap)+                                              :: CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Assumption A",+                  "For a \"wrap :: B -> A\" and an \"unwrap :: A -> B\", then",+                  "wrap (unwrap a)  <==>  a",+                  "Note: only use this if it's true!"+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-assumption-B-unsafe" ((\ wrap unwrap f -> promoteExprBiR $ wwB Nothing wrap unwrap f)+                                              :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Assumption B",+                  "For a \"wrap :: B -> A\", an \"unwrap :: A -> B\", and an \"f :: A -> A\", then",+                  "wrap (unwrap (f a))  <==>  f a",+                  "Note: only use this if it's true!"+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-assumption-C-unsafe" ((\ wrap unwrap f -> promoteExprBiR $ wwC Nothing wrap unwrap f)+                                              :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Assumption C",+                  "For a \"wrap :: B -> A\", an \"unwrap :: A -> B\", and an \"f :: A -> A\", then",+                  "fix A (\\ a -> wrap (unwrap (f a)))  <==>  fix A f",+                  "Note: only use this if it's true!"+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-AssA-to-AssB" (promoteExprR . wwAssAimpliesAssB . extractR :: RewriteH Core -> RewriteH Core)+                   [ "Convert a proof of worker/wrapper Assumption A into a proof of worker/wrapper Assumption B."+                   ]+         , external "ww-AssB-to-AssC" (promoteExprR . wwAssBimpliesAssC . extractR :: RewriteH Core -> RewriteH Core)+                   [ "Convert a proof of worker/wrapper Assumption B into a proof of worker/wrapper Assumption C."+                   ]+         , external "ww-AssA-to-AssC" (promoteExprR . wwAssAimpliesAssC . extractR :: RewriteH Core -> RewriteH Core)+                   [ "Convert a proof of worker/wrapper Assumption A into a proof of worker/wrapper Assumption C."+                   ]+         , external "ww-generate-fusion" (wwGenerateFusionR . mkWWAssC :: RewriteH Core -> RewriteH Core)+                   [ "Given a proof of Assumption C (fix A (\\ a -> wrap (unwrap (f a))) ==> fix A f), then",+                     "execute this command on \"work = unwrap (f (wrap work))\" to enable the \"ww-fusion\" rule thereafter.",+                     "Note that this is performed automatically as part of \"ww-split\"."+                   ] .+ Experiment .+ TODO+         , external "ww-generate-fusion-unsafe" (wwGenerateFusionR Nothing :: RewriteH Core)+                   [ "Execute this command on \"work = unwrap (f (wrap work))\" to enable the \"ww-fusion\" rule thereafter.",+                     "The precondition \"fix A (wrap . unwrap . f) == fix A f\" is expected to hold.",+                     "Note that this is performed automatically as part of \"ww-split\"."+                   ] .+ Experiment .+ TODO+         , external "ww-fusion" (promoteExprBiR wwFusion :: BiRewriteH Core)+                [ "Worker/Wrapper Fusion",+                  "unwrap (wrap work)  <==>  work",+                  "Note: you are required to have previously executed the command \"ww-generate-fusion\" on the definition",+                  "      work = unwrap (f (wrap work))"+                ] .+ Introduce .+ Context .+ PreCondition .+ TODO+         ]+  where+    mkWWAssC :: RewriteH Core -> Maybe WWAssumption+    mkWWAssC r = Just (WWAssumption C (extractR r))++--------------------------------------------------------------------------------------------------++-- | For any @f :: A -> A@, and given @wrap :: B -> A@ and @unwrap :: A -> B@ as arguments, then+--   @fix A f@  \<==\>  @wrap (fix B (\\ b -> unwrap (f (wrap b))))@+wwFacBR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr+wwFacBR mAss wrap unwrap = beforeBiR (wrapUnwrapTypes wrap unwrap)+                                                (\ (tyA,tyB) -> bidirectional (wwL tyA tyB) wwR)+  where+    wwL :: Type -> Type -> RewriteH CoreExpr+    wwL tyA tyB = prefixFailMsg "worker/wrapper factorisation failed: " $+                  do (tA,f) <- isFixExprT+                     guardMsg (eqType tyA tA) ("wrapper/unwrapper types do not match fix body type.")+                     whenJust (verifyWWAss wrap unwrap f) mAss+                     b <- constT (newIdH "x" tyB)+                     App wrap <$> mkFixT (Lam b (App unwrap (App f (App wrap (Var b)))))++    wwR :: RewriteH CoreExpr+    wwR  =    prefixFailMsg "(reverse) worker/wrapper factorisation failed: " $+              withPatFailMsg "not an application." $+              do App wrap2 fx <- idR+                 withPatFailMsg wrongFixBody $+                   do (_, Lam b (App unwrap1 (App f (App wrap1 (Var b'))))) <- isFixExprT <<< constant fx+                      guardMsg (b == b') wrongFixBody+                      guardMsg (equivalentBy exprAlphaEq [wrap, wrap1, wrap2]) "wrappers do not match."+                      guardMsg (exprAlphaEq unwrap unwrap1) "unwrappers do not match."+                      whenJust (verifyWWAss wrap unwrap f) mAss+                      mkFixT f++    wrongFixBody :: String+    wrongFixBody = "body of fix does not have the form Lam b (App unwrap (App f (App wrap (Var b))))"++-- | For any @f :: A -> A@, and given @wrap :: B -> A@ and @unwrap :: A -> B@ as arguments, then+--   @fix A f@  \<==\>  @wrap (fix B (\\ b -> unwrap (f (wrap b))))@+wwFac :: Maybe WWAssumption -> CoreString -> CoreString -> BiRewriteH CoreExpr+wwFac mAss = parse2beforeBiR (wwFacBR mAss)++--------------------------------------------------------------------------------------------------++-- | Given @wrap :: B -> A@, @unwrap :: A -> B@ and @work :: B@ as arguments, then+--   @unwrap (wrap work)@  \<==\>  @work@+wwFusionBR :: BiRewriteH CoreExpr+wwFusionBR =+    beforeBiR (prefixFailMsg "worker/wrapper fusion failed: " $+               withPatFailMsg "malformed WW Fusion rule." $+               do Def w (App unwrap (App _f (App wrap (Var w')))) <- constT (lookupDef workLabel)+                  guardMsg (w == w') "malformed WW Fusion rule."+                  return (wrap,unwrap,Var w)+              )+              (\ (wrap,unwrap,work) -> bidirectional (fusL wrap unwrap work) (fusR wrap unwrap work))+  where+    fusL :: CoreExpr -> CoreExpr -> CoreExpr -> RewriteH CoreExpr+    fusL wrap unwrap work =+           prefixFailMsg "worker/wrapper fusion failed: " $+           withPatFailMsg (wrongExprForm "unwrap (wrap work)") $+           do App unwrap' (App wrap' work') <- idR+              guardMsg (exprAlphaEq wrap wrap') "wrapper does not match."+              guardMsg (exprAlphaEq unwrap unwrap') "unwrapper does not match."+              guardMsg (exprAlphaEq work work') "worker does not match."+              return work++    fusR :: CoreExpr -> CoreExpr -> CoreExpr -> RewriteH CoreExpr+    fusR wrap unwrap work =+           prefixFailMsg "(reverse) worker/wrapper fusion failed: " $+           do work' <- idR+              guardMsg (exprAlphaEq work work') "worker does not match."+              return $ App unwrap (App wrap work)+++-- | Given @wrap :: B -> A@, @unwrap :: A -> B@ and @work :: B@ as arguments, then+--   @unwrap (wrap work)@  \<==\>  @work@+wwFusion :: BiRewriteH CoreExpr+wwFusion = wwFusionBR++--------------------------------------------------------------------------------------------------++-- | Save the recursive definition of work in the stash, so that we can later verify uses of 'wwFusionBR'.+--   Must be applied to a definition of the form: @work = unwrap (f (wrap work))@+--   Note that this is performed automatically as part of 'wwSplitR'.+wwGenerateFusionR :: Maybe WWAssumption -> RewriteH Core+wwGenerateFusionR mAss =+    prefixFailMsg "generate WW fusion failed: " $+    withPatFailMsg wrongForm $+    do Def w (App unwrap (App f (App wrap (Var w')))) <- projectT+       guardMsg (w == w') wrongForm+       whenJust (verifyWWAss wrap unwrap f) mAss+       rememberR workLabel+  where+    wrongForm = "definition does not have the form: work = unwrap (f (wrap work))"++--------------------------------------------------------------------------------------------------++-- | \\ wrap unwrap ->  (@prog = expr@  ==>  @prog = let f = \\ prog -> expr in let work = unwrap (f (wrap work)) in wrap work)@+wwSplitR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> RewriteH CoreDef+wwSplitR mAss wrap unwrap =+  let work = TH.mkName "work"+      fx   = TH.mkName "fix"+   in+      fixIntroR+      >>> defAllR idR ( appAllR idR (letIntroR "f")+                        >>> letFloatArgR+                        >>> letAllR idR ( forwardT (wwFacBR mAss wrap unwrap)+                                          >>> appAllR idR ( unfoldNameR fx+                                                            >>> alphaLetWithR [work]+                                                            >>> letRecAllR (\ _ -> defAllR idR (betaReduceR >>> letNonRecSubstR)+                                                                                   >>> extractR (wwGenerateFusionR mAss)+                                                                           )+                                                                           idR+                                                          )+                                          >>> letFloatArgR+                                        )+                      )++-- | \\ wrap unwrap ->  (@prog = expr@  ==>  @prog = let f = \\ prog -> expr in let work = unwrap (f (wrap work)) in wrap work)@+wwSplit :: Maybe WWAssumption -> CoreString -> CoreString -> RewriteH CoreDef+wwSplit mAss wrapS unwrapS = (parseCoreExprT wrapS &&& parseCoreExprT unwrapS) >>= uncurry (wwSplitR mAss)++-- | As 'wwSplit' but performs the static-argument transformation for @n@ static arguments first, and optionally provides some of those arguments (specified by index) to all calls of wrap and unwrap.+--   This is useful if, for example, the expression, and wrap and unwrap, all have a @forall@ type.+wwSplitStaticArg :: Int -> [Int] -> Maybe WWAssumption -> CoreString -> CoreString -> RewriteH CoreDef+wwSplitStaticArg 0 _  = wwSplit+wwSplitStaticArg n is = \ mAss wrapS unwrapS ->+                            prefixFailMsg "worker/wrapper split (static argument variant) failed: " $+                            do guardMsg (all (< n) is) "arguments for wrap and unwrap must be chosen from the statically transformed arguments."+                               bs <- defT successT (arr collectBinders) (\ () -> take n . fst)+                               let args = varsToCoreExprs [ b | (i,b) <- zip [0..] bs, i `elem` is ]++                               staticArgPosR [0..(n-1)] >>> defAllR idR+                                                                    (let wwSplitArgsR :: RewriteH CoreDef+                                                                         wwSplitArgsR = do wrap   <- parseCoreExprT wrapS+                                                                                           unwrap <- parseCoreExprT unwrapS+                                                                                           wwSplitR mAss (mkCoreApps wrap args) (mkCoreApps unwrap args)+                                                                      in+                                                                         extractR $ do p <- considerConstructT LetExpr+                                                                                       localPathR p $ promoteExprR (letRecAllR (const wwSplitArgsR) idR >>> letSubstR)+                                                                    )+++--------------------------------------------------------------------------------------------------++-- | Convert a proof of WW Assumption A into a proof of WW Assumption B.+wwAssAimpliesAssB :: RewriteH CoreExpr -> RewriteH CoreExpr+wwAssAimpliesAssB = id++-- | Convert a proof of WW Assumption B into a proof of WW Assumption C.+wwAssBimpliesAssC :: RewriteH CoreExpr -> RewriteH CoreExpr+wwAssBimpliesAssC assB = appAllR idR (lamAllR idR assB >>> etaReduceR)++-- | Convert a proof of WW Assumption A into a proof of WW Assumption C.+wwAssAimpliesAssC :: RewriteH CoreExpr -> RewriteH CoreExpr+wwAssAimpliesAssC =  wwAssBimpliesAssC . wwAssAimpliesAssB++--------------------------------------------------------------------------------------------------++-- | @wrap (unwrap a)@  \<==\>  @a@+wwAssA :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption A+       -> CoreExpr                  -- ^ wrap+       -> CoreExpr                  -- ^ unwrap+       -> BiRewriteH CoreExpr+wwAssA mr wrap unwrap = beforeBiR (do whenJust (verifyAssA wrap unwrap) mr+                                      wrapUnwrapTypes wrap unwrap+                                  )+                                  (\ (tyA,_) -> bidirectional wwAL (wwAR tyA))+  where+    wwAL :: RewriteH CoreExpr+    wwAL = withPatFailMsg (wrongExprForm "App wrap (App unwrap x)") $+           do App wrap' (App unwrap' x) <- idR+              guardMsg (exprAlphaEq wrap wrap')     "given wrapper does not match wrapper in expression."+              guardMsg (exprAlphaEq unwrap unwrap') "given unwrapper does not match unwrapper in expression."+              return x++    wwAR :: Type -> RewriteH CoreExpr+    wwAR tyA = do x <- idR+                  guardMsg (exprKindOrType x `eqType` tyA) "type of expression does not match types of wrap/unwrap."+                  return $ App wrap (App unwrap x)++-- | @wrap (unwrap a)@  \<==\>  @a@+wwA :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption A+    -> CoreString                -- ^ wrap+    -> CoreString                -- ^ unwrap+    -> BiRewriteH CoreExpr+wwA mr = parse2beforeBiR (wwAssA mr)++-- | @wrap (unwrap (f a))@  \<==\>  @f a@+wwAssB :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption B+       -> CoreExpr                  -- ^ wrap+       -> CoreExpr                  -- ^ unwrap+       -> CoreExpr                  -- ^ f+       -> BiRewriteH CoreExpr+wwAssB mr wrap unwrap f = beforeBiR (whenJust (verifyAssB wrap unwrap f) mr)+                                    (\ () -> bidirectional wwBL wwBR)+  where+    assA :: BiRewriteH CoreExpr+    assA = wwAssA Nothing wrap unwrap++    wwBL :: RewriteH CoreExpr+    wwBL = withPatFailMsg (wrongExprForm "App wrap (App unwrap (App f a))") $+           do App _ (App _ (App f' _)) <- idR+              guardMsg (exprAlphaEq f f') "given body function does not match expression."+              forwardT assA++    wwBR :: RewriteH CoreExpr+    wwBR = withPatFailMsg (wrongExprForm "App f a") $+           do App f' _ <- idR+              guardMsg (exprAlphaEq f f') "given body function does not match expression."+              backwardT assA++-- | @wrap (unwrap (f a))@  \<==\>  @f a@+wwB :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption B+    -> CoreString                -- ^ wrap+    -> CoreString                -- ^ unwrap+    -> CoreString                -- ^ f+    -> BiRewriteH CoreExpr+wwB mr = parse3beforeBiR (wwAssB mr)++-- | @fix A (\ a -> wrap (unwrap (f a)))@  \<==\>  @fix A f@+wwAssC :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption C+       -> CoreExpr                  -- ^ wrap+       -> CoreExpr                  -- ^ unwrap+       -> CoreExpr                  -- ^ f+       -> BiRewriteH CoreExpr+wwAssC mr wrap unwrap f = beforeBiR (do _ <- isFixExprT+                                        whenJust (verifyAssC wrap unwrap f) mr+                                    )+                                    (\ () -> bidirectional wwCL wwCR)+  where+    assB :: BiRewriteH CoreExpr+    assB = wwAssB Nothing wrap unwrap f++    wwCL :: RewriteH CoreExpr+    wwCL = wwAssBimpliesAssC (forwardT assB)++    wwCR :: RewriteH CoreExpr+    wwCR = appAllR idR (etaExpandR "a" >>> lamAllR idR (backwardT assB))++-- | @fix A (\ a -> wrap (unwrap (f a)))@  \<==\>  @fix A f@+wwC :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption C+    -> CoreString                -- ^ wrap+    -> CoreString                -- ^ unwrap+    -> CoreString                -- ^ f+    -> BiRewriteH CoreExpr+wwC mr = parse3beforeBiR (wwAssC mr)++--------------------------------------------------------------------------------------------------++verifyWWAss :: CoreExpr        -- ^ wrap+            -> CoreExpr        -- ^ unwrap+            -> CoreExpr        -- ^ f+            -> WWAssumption+            -> TranslateH x ()+verifyWWAss wrap unwrap f (WWAssumption tag ass) =+    case tag of+      A -> verifyAssA wrap unwrap ass+      B -> verifyAssB wrap unwrap f ass+      C -> verifyAssC wrap unwrap f ass++verifyAssA :: CoreExpr          -- ^ wrap+           -> CoreExpr          -- ^ unwrap+           -> RewriteH CoreExpr -- ^ WW Assumption A+           -> TranslateH x ()+verifyAssA wrap unwrap assA =+  prefixFailMsg ("verification of worker/wrapper Assumption A failed: ") $+  do _ <- wrapUnwrapTypes wrap unwrap -- this check is redundant, but will produce a better error message+     verifyRetractionT wrap unwrap assA++verifyAssB :: CoreExpr          -- ^ wrap+           -> CoreExpr          -- ^ unwrap+           -> CoreExpr          -- ^ f+           -> RewriteH CoreExpr -- ^ WW Assumption B+           -> TranslateH x ()+verifyAssB wrap unwrap f assB =+  prefixFailMsg ("verification of worker/wrapper assumption B failed: ") $+  do (tyA,_) <- wrapUnwrapTypes wrap unwrap+     a       <- constT (newIdH "a" tyA)+     let lhs = App wrap (App unwrap (App f (Var a)))+         rhs = App f (Var a)+     verifyEqualityLeftToRightT lhs rhs assB++verifyAssC :: CoreExpr          -- ^ wrap+           -> CoreExpr          -- ^ unwrap+           -> CoreExpr          -- ^ f+           -> RewriteH CoreExpr -- ^ WW Assumption C+           -> TranslateH a ()+verifyAssC wrap unwrap f assC =+  prefixFailMsg ("verification of worker/wrapper assumption C failed: ") $+  do (tyA,_) <- wrapUnwrapTypes wrap unwrap+     a       <- constT (newIdH "a" tyA)+     rhs     <- mkFixT f+     lhs     <- mkFixT (Lam a (App wrap (App unwrap (App f (Var a)))))+     verifyEqualityLeftToRightT lhs rhs assC++--------------------------------------------------------------------------------------------------++wrapUnwrapTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type,Type)+wrapUnwrapTypes wrap unwrap = setFailMsg "given expressions have the wrong types to form a valid wrap/unwrap pair." $+                              funsWithInverseTypes unwrap wrap++--------------------------------------------------------------------------------------------------
+ src/HERMIT/Dictionary/WorkerWrapper/FixResult.hs view
@@ -0,0 +1,502 @@+{-# LANGUAGE TupleSections #-}++module HERMIT.Dictionary.WorkerWrapper.FixResult+       ( -- * The Worker/Wrapper Transformation (Result Variant)+         -- | Note that many of these operations require 'Data.Function.fix' to be in scope.+         HERMIT.Dictionary.WorkerWrapper.FixResult.externals+       , wwResultFacBR+       , wwResultSplitR+       , wwResultSplitStaticArg+       , wwResultGenerateFusionR+       , wwResultFusionBR+       , wwResultAssA+       , wwResultAssB+       , wwResultAssC+       )+where++import Prelude hiding (abs)++import Control.Arrow++import HERMIT.Core+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.External+import HERMIT.GHC+import HERMIT.Utilities+import HERMIT.ParserCore++import HERMIT.Dictionary.AlphaConversion+import HERMIT.Dictionary.Common+import HERMIT.Dictionary.Function+import HERMIT.Dictionary.Local+import HERMIT.Dictionary.Navigation+import HERMIT.Dictionary.FixPoint+import HERMIT.Dictionary.Reasoning+import HERMIT.Dictionary.Unfold++import HERMIT.Dictionary.WorkerWrapper.Common++import qualified Language.Haskell.TH as TH++--------------------------------------------------------------------------------------------------++-- | Externals for manipulating fixed points, and for the worker/wrapper transformation.+externals ::  [External]+externals =+         [+           external "ww-result-factorisation" ((\ abs rep assC -> promoteExprBiR $ wwFac (mkWWAssC assC) abs rep)+                                          :: CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Factorisation (Result Variant)",+                  "For any \"f :: (X -> A) -> (X -> A)\", and given \"abs :: B -> A\" and \"rep :: A -> B\" as arguments,",+                  "and a proof of Assumption C (fix (X -> A) (\\ h x -> abs (rep (f h x))) ==> fix (X->A) f), then",+                  "fix (X->A) f  ==>  \\ x1 -> abs (fix (X->B) (\\ h x2 -> rep (f (\\ x3 -> abs (h x3)) x2)) x1"+                ] .+ Introduce .+ Context+         , external "ww-result-factorisation-unsafe" ((\ abs rep -> promoteExprBiR $ wwFac Nothing abs rep)+                                               :: CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Factorisation (Result Variant)",+                  "For any \"f :: (X -> A) -> (X -> A)\", and given \"abs :: B -> A\" and \"rep :: A -> B\" as arguments, then",+                  "fix (X->A) f  ==>  \\ x1 -> abs (fix (X->B) (\\ h x2 -> rep (f (\\ x3 -> abs (h x3)) x2)) x1",+                  "Note: the pre-condition \"fix (X -> A) (\\ h x -> abs (rep (f h x))) == fix (X->A) f\" is expected to hold."+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-result-split" ((\ abs rep assC -> promoteDefR $ wwSplit (mkWWAssC assC) abs rep)+                                  :: CoreString -> CoreString -> RewriteH Core -> RewriteH Core)+                [ "Worker/Wrapper Split (Result Variant)",+                  "For any \"prog :: X -> A\", and given \"abs :: B -> A\" and \"rep :: A -> B\" as arguments,",+                  "and a proof of Assumption C (fix (X->A) (\\ h x -> abs (rep (f h x))) ==> fix (X->A) f), then",+                  "prog = expr  ==>  prog = let f = \\ prog -> expr",+                  "                          in let work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)",+                  "                              in \\ x0 -> abs (work x0)"+                ] .+ Introduce .+ Context+         , external "ww-result-split-unsafe" ((\ abs rep -> promoteDefR $ wwSplit Nothing abs rep)+                                       :: CoreString -> CoreString -> RewriteH Core)+                [ "Unsafe Worker/Wrapper Split (Result Variant)",+                  "For any \"prog :: X -> A\", and given \"abs :: B -> A\" and \"rep :: A -> B\" as arguments, then",+                  "prog = expr  ==>  prog = let f = \\ prog -> expr",+                  "                          in let work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)",+                  "                              in \\ x0 -> abs (work x0)",+                  "Note: the pre-condition \"fix (X->A) (\\ h x -> abs (rep (f h x))) == fix (X->A) f\" is expected to hold."+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-result-split-static-arg" ((\ n is abs rep assC -> promoteDefR $ wwResultSplitStaticArg n is (mkWWAssC assC) abs rep)+                                      :: Int -> [Int] -> CoreString -> CoreString -> RewriteH Core -> RewriteH Core)+                [ "Worker/Wrapper Split - Static Argument Variant (Result Variant)",+                  "Perform the static argument transformation on the first n arguments, then perform the worker/wrapper split,",+                  "applying the given abs and rep functions to the specified (by index) static arguments before use."+                ] .+ Introduce .+ Context+         , external "ww-result-split-static-arg-unsafe" ((\ n is abs rep -> promoteDefR $ wwResultSplitStaticArg n is Nothing abs rep)+                                      :: Int -> [Int] -> CoreString -> CoreString -> RewriteH Core)+                [ "Unsafe Worker/Wrapper Split - Static Argument Variant (Result Variant)",+                  "Perform the static argument transformation on the first n arguments, then perform the (unsafe) worker/wrapper split,",+                  "applying the given abs and rep functions to the specified (by index) static arguments before use."+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-result-assumption-A" ((\ abs rep assA -> promoteExprBiR $ wwA (Just $ extractR assA) abs rep)+                                       :: CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Assumption A (Result Variant)",+                  "For a \"abs :: B -> A\" and a \"rep :: A -> B\",",+                  "and given a proof of \"abs (rep a)  ==>  a\", then",+                  "abs (rep a)  <==>  a"+                ] .+ Introduce .+ Context+         , external "ww-result-assumption-B" ((\ abs rep f assB -> promoteExprBiR $ wwB (Just $ extractR assB) abs rep f)+                                       :: CoreString -> CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Assumption B (Result Variant)",+                  "For a \"abs :: B -> A\", an \"rep :: A -> B\", and an \"f :: (X -> A) -> X -> A\",",+                  "and given a proof of \"abs (rep (f h x))  ==>  f h x\", then",+                  "abs (rep (f h x))  <==>  f h x"+                ] .+ Introduce .+ Context+         , external "ww-result-assumption-C" ((\ abs rep f assC -> promoteExprBiR $ wwC (Just $ extractR assC) abs rep f)+                                       :: CoreString -> CoreString -> CoreString -> RewriteH Core -> BiRewriteH Core)+                [ "Worker/Wrapper Assumption C (Result Variant)",+                  "For a \"abs :: B -> A\", an \"rep :: A -> B\", and an \"f :: (X -> A) -> X -> A\",",+                  "and given a proof of \"fix (X->A) (\\ h x -> abs (rep (f h x))) ==> fix (X->A) f\", then",+                  "fix (X->A) (\\ h x -> abs (rep (f h x)))  <==>  fix (X->A) f"+                ] .+ Introduce .+ Context+         , external "ww-result-assumption-A-unsafe" ((\ abs rep -> promoteExprBiR $ wwA Nothing abs rep)+                                              :: CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Assumption A (Result Variant)",+                  "For a \"abs :: B -> A\" and a \"rep :: A -> B\", then",+                  "abs (rep a)  <==>  a",+                  "Note: only use this if it's true!"+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-result-assumption-B-unsafe" ((\ abs rep f -> promoteExprBiR $ wwB Nothing abs rep f)+                                              :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Assumption B (Result Variant)",+                  "For a \"abs :: B -> A\", an \"rep :: A -> B\", and an \"f :: (X -> A) -> X -> A\", then",+                  "abs (rep (f h x))  <==>  f h x",+                  "Note: only use this if it's true!"+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-result-assumption-C-unsafe" ((\ abs rep f -> promoteExprBiR $ wwC Nothing abs rep f)+                                              :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)+                [ "Unsafe Worker/Wrapper Assumption C (Result Variant)",+                  "For a \"abs :: B -> A\", an \"rep :: A -> B\", and an \"f :: (X -> A) -> X -> A\", then",+                  "fix (X->A) (\\ h x -> abs (rep (f h x)))  <==>  fix (X->A) f",+                  "Note: only use this if it's true!"+                ] .+ Introduce .+ Context .+ PreCondition+         , external "ww-result-AssA-to-AssB" (promoteExprR . wwResultAssAimpliesAssB . extractR :: RewriteH Core -> RewriteH Core)+                   [ "Convert a proof of worker/wrapper Assumption A into a proof of worker/wrapper Assumption B."+                   ]+         , external "ww-result-AssB-to-AssC" (promoteExprR . wwResultAssBimpliesAssC . extractR :: RewriteH Core -> RewriteH Core)+                   [ "Convert a proof of worker/wrapper Assumption B into a proof of worker/wrapper Assumption C."+                   ]+         , external "ww-result-AssA-to-AssC" (promoteExprR . wwResultAssAimpliesAssC . extractR :: RewriteH Core -> RewriteH Core)+                   [ "Convert a proof of worker/wrapper Assumption A into a proof of worker/wrapper Assumption C."+                   ]+         , external "ww-result-generate-fusion" (wwResultGenerateFusionR . mkWWAssC :: RewriteH Core -> RewriteH Core)+                   [ "Given a proof of Assumption C (fix (X->A) (\\ h x -> abs (rep (f h x))) ==> fix (X->A) f), then",+                     "execute this command on \"work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)\" to enable the \"ww-result-fusion\" rule thereafter.",+                     "Note that this is performed automatically as part of \"ww-result-split\"."+                   ] .+ Experiment .+ TODO+         , external "ww-result-generate-fusion-unsafe" (wwResultGenerateFusionR Nothing :: RewriteH Core)+                   [ "Execute this command on \"work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)\" to enable the \"ww-fusion\" rule thereafter.",+                     "The precondition \"fix (X->A) (\\ h x -> abs (rep (f h x))) == fix (X->A) f\" is expected to hold.",+                     "Note that this is performed automatically as part of \"ww-result-split\"."+                   ] .+ Experiment .+ TODO+         , external "ww-result-fusion" (promoteExprBiR wwFusion :: BiRewriteH Core)+                [ "Worker/Wrapper Fusion (Result Variant)",+                  "rep (abs (work x))  <==>  work x",+                  "Note: you are required to have previously executed the command \"ww-generate-fusion\" on the definition",+                  "      work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)"+                ] .+ Introduce .+ Context .+ PreCondition .+ TODO+         ]+  where+    mkWWAssC :: RewriteH Core -> Maybe WWAssumption+    mkWWAssC r = Just (WWAssumption C (extractR r))++--------------------------------------------------------------------------------------------------+++-- | For any @f :: (X -> A) -> (X -> A)@, and given @abs :: B -> A@ and @rep :: A -> B@ as arguments, then+--   @fix A f@  \<==\>  @\\ x1 -> abs (fix (X->B) (\\ h x2 -> rep (f (\\ x3 -> abs (h x3)) x2)) x1)@+wwResultFacBR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr+wwResultFacBR mAss abs rep = beforeBiR (absRepTypes abs rep)+                                  (\ (tyA,tyB) -> bidirectional (wwL tyA tyB) wwR)+  where+    wwL :: Type -> Type -> RewriteH CoreExpr+    wwL tyA tyB = prefixFailMsg "worker/wrapper factorisation failed: " $+                  do (tyXA,f)  <- isFixExprT+                     (tyX,tA)  <- constT (splitFunTypeM tyXA)+                     let tyXB  =  FunTy tyX tyB+                     h         <- constT (newIdH "h" tyXB)+                     guardMsg (eqType tyA tA) ("abs/rep types do not match fix body type.")+                     x0        <- constT (newIdH "x0" tyX)+                     x1        <- constT (newIdH "x1" tyX)+                     x2        <- constT (newIdH "x2" tyX)++                     whenJust (verifyWWAss abs rep f) mAss++                     work <- mkFixT (Lam h (Lam x1 (App rep+                                                        (App (App f (Lam x2 (App abs (App (Var h) (Var x2)))))+                                                             (Var x1)+                                                        )+                                                   )))+                     return (Lam x0 (App abs (App work (Var x0))))++    wwR :: RewriteH CoreExpr+    wwR  =    prefixFailMsg "(reverse) worker/wrapper factorisation failed: " $+              withPatFailMsg wrongForm $+              do Lam x0 (App abs2 (App fx (Var x0'))) <- idR+                 guardMsg (x0 == x0') wrongForm+                 (_, Lam h (Lam x1 (App rep1+                                        (App (App f (Lam x2 (App abs1 (App (Var h') (Var x2')))))+                                             (Var x1')+                                        )+                                  ))) <- isFixExprT <<< constant fx+                 guardMsg (x1 == x1' && x2 == x2' && h == h') wrongForm+                 guardMsg (equivalentBy exprAlphaEq [abs, abs1, abs2]) "abs's do not match."+                 guardMsg (exprAlphaEq rep rep1) "rep's do not match."+                 whenJust (verifyWWAss abs rep f) mAss+                 mkFixT f++    wrongForm :: String+    wrongForm = wrongExprForm "\\ x1 -> abs (fix (\\ h x2 -> rep (f (\\ x3 -> abs (h x3)) x2)) x1)"++-- | For any @f :: (X -> A) -> (X -> A)@, and given @abs :: B -> A@ and @rep :: A -> B@ as arguments, then+--   @fix A f@  \<==\>  @\\ x1 -> abs (fix (X->B) (\\ h x2 -> rep (f (\\ x3 -> abs (h x3)) x2)) x1)@+wwFac :: Maybe WWAssumption -> CoreString -> CoreString -> BiRewriteH CoreExpr+wwFac mAss = parse2beforeBiR (wwResultFacBR mAss)++--------------------------------------------------------------------------------------------------++-- | Given @abs :: B -> A@, @rep :: A -> B@ and @work :: X -> B@ as arguments, then+--   @rep (abs (work x))@  \<==\>  @work x@+wwResultFusionBR :: BiRewriteH CoreExpr+wwResultFusionBR =+    beforeBiR (prefixFailMsg "worker/wrapper fusion failed: " $+               withPatFailMsg "malformed WW Fusion rule." $+               do Def w (Lam x1 (App rep+                                     (App (App _ (Lam x2 (App abs (App (Var w') (Var x2')))))+                                          (Var x1')+                                     )+                                )+                        ) <- constT (lookupDef workLabel)+                  guardMsg (w == w' && x1 == x1' && x2 == x2') "malformed WW Fusion rule."+                  return (abs,rep,Var w)+              )+              (\ (abs,rep,work) -> bidirectional (fusL abs rep work) (fusR abs rep work))+  where+    fusL :: CoreExpr -> CoreExpr -> CoreExpr -> RewriteH CoreExpr+    fusL abs rep work =+           prefixFailMsg "worker/wrapper fusion failed: " $+           withPatFailMsg (wrongExprForm "rep (abs (work x))") $+           do App rep' (App abs' (App work' x)) <- idR+              guardMsg (exprAlphaEq abs abs') "abs does not match."+              guardMsg (exprAlphaEq rep rep') "rep does not match."+              guardMsg (exprAlphaEq work work') "worker does not match."+              return $ App work x++    fusR :: CoreExpr -> CoreExpr -> CoreExpr -> RewriteH CoreExpr+    fusR abs rep work =+           prefixFailMsg "(reverse) worker/wrapper fusion failed: " $+           withPatFailMsg (wrongExprForm "work x") $+           do App work' x <- idR+              guardMsg (exprAlphaEq work work') "worker does not match."+              return $ App rep (App abs (App work x))++-- | Given @abs :: B -> A@, @rep :: A -> B@ and @work :: X -> B@ as arguments, then+--   @rep (abs (work x))@  \<==\>  @work x@+wwFusion :: BiRewriteH CoreExpr+wwFusion = wwResultFusionBR++--------------------------------------------------------------------------------------------------++-- | Save the recursive definition of work in the stash, so that we can later verify uses of 'wwResultFusionBR'.+--   Must be applied to a definition of the form: @work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)@+--   Note that this is performed automatically as part of 'wwResultSplitR'.+wwResultGenerateFusionR :: Maybe WWAssumption -> RewriteH Core+wwResultGenerateFusionR mAss =+    prefixFailMsg "generate WW fusion failed: " $+    withPatFailMsg wrongForm $+    do Def w (Lam x1 (App rep+                          (App (App f (Lam x2 (App abs (App (Var w') (Var x2')))))+                               (Var x1')+                          )+                     )+             ) <- projectT+       guardMsg (w == w' && x1 == x1' && x2 == x2') wrongForm+       whenJust (verifyWWAss abs rep f) mAss+       rememberR workLabel+  where+    wrongForm = "definition does not have the form: work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1)"+++--------------------------------------------------------------------------------------------------++-- | \\ abs rep -> (@prog = expr@  ==>  @prog = let f = \\ prog -> expr in let work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1) in \\ x0 -> abs (work x0)@)+wwResultSplitR :: Maybe WWAssumption -> CoreExpr -> CoreExpr -> RewriteH CoreDef+wwResultSplitR mAss abs rep =+  let work = TH.mkName "work"+      fx   = TH.mkName "fix"+   in+      fixIntroR+      >>> defAllR idR ( appAllR idR (letIntroR "f")+                        >>> letFloatArgR+                        >>> letAllR idR ( forwardT (wwResultFacBR mAss abs rep)+                                          >>> lamAllR idR (appAllR idR (appAllR ( unfoldNameR fx+                                                                                  >>> alphaLetWithR [work]+                                                                                  >>> letRecAllR (\ _ -> defAllR idR (betaReduceR >>> letNonRecSubstR)+                                                                                                         >>> extractR (wwResultGenerateFusionR mAss)+                                                                                                 )+                                                                                                 idR+                                                                                )+                                                                                idR+                                                                        >>> letFloatAppR+                                                                       )+                                                           >>> letFloatArgR+                                                          )+                                          >>> letFloatLamR+                                        )+                      )++-- | \\ abs rep -> (@prog = expr@  ==>  @prog = let f = \\ prog -> expr in let work = \\ x1 -> rep (f (\\ x2 -> abs (work x2)) x1) in \\ x0 -> abs (work x0))@+wwSplit :: Maybe WWAssumption -> CoreString -> CoreString -> RewriteH CoreDef+wwSplit mAss absS repS = (parseCoreExprT absS &&& parseCoreExprT repS) >>= uncurry (wwResultSplitR mAss)++-- | As 'wwSplit' but performs the static-argument transformation for @n@ static arguments first, and optionally provides some of those arguments (specified by index) to all calls of abs and rep.+--   This is useful if, for example, the expression, and abs and rep, all have a @forall@ type.+wwResultSplitStaticArg :: Int -> [Int] -> Maybe WWAssumption -> CoreString -> CoreString -> RewriteH CoreDef+wwResultSplitStaticArg 0 _  = wwSplit+wwResultSplitStaticArg n is = \ mAss absS repS ->+                            prefixFailMsg "worker/wrapper split (static argument variant) failed: " $+                            do guardMsg (all (< n) is) "arguments for abs and rep must be chosen from the statically transformed arguments."+                               bs <- defT successT (arr collectBinders) (\ () -> take n . fst)+                               let args = varsToCoreExprs [ b | (i,b) <- zip [0..] bs, i `elem` is ]++                               staticArgPosR [0..(n-1)] >>> defAllR idR+                                                                    (let wwSplitArgsR :: RewriteH CoreDef+                                                                         wwSplitArgsR = do abs  <- parseCoreExprT absS+                                                                                           rep  <- parseCoreExprT repS+                                                                                           wwResultSplitR mAss (mkCoreApps abs args) (mkCoreApps rep args)+                                                                      in+                                                                         extractR $ do p <- considerConstructT LetExpr+                                                                                       localPathR p $ promoteExprR (letRecAllR (const wwSplitArgsR) idR >>> letSubstR)+                                                                    )++--------------------------------------------------------------------------------------------------++-- | Convert a proof of WW Assumption A into a proof of WW Assumption B.+wwResultAssAimpliesAssB :: RewriteH CoreExpr -> RewriteH CoreExpr+wwResultAssAimpliesAssB = id++-- | Convert a proof of WW Assumption B into a proof of WW Assumption C.+wwResultAssBimpliesAssC :: RewriteH CoreExpr -> RewriteH CoreExpr+wwResultAssBimpliesAssC assB = appAllR idR (lamAllR idR (lamAllR idR assB >>> etaReduceR) >>> etaReduceR)++-- | Convert a proof of WW Assumption A into a proof of WW Assumption C.+wwResultAssAimpliesAssC :: RewriteH CoreExpr -> RewriteH CoreExpr+wwResultAssAimpliesAssC =  wwResultAssBimpliesAssC . wwResultAssAimpliesAssB++--------------------------------------------------------------------------------------------------++-- | @abs (rep a)@  \<==\>  @a@+wwResultAssA :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption A+       -> CoreExpr                  -- ^ abs+       -> CoreExpr                  -- ^ rep+       -> BiRewriteH CoreExpr+wwResultAssA mr abs rep = beforeBiR+                      (do whenJust (verifyAssA abs rep) mr+                          absRepTypes abs rep+                      )+                      (\ (tyA,_) -> bidirectional wwAL (wwAR tyA))+  where+    wwAL :: RewriteH CoreExpr+    wwAL = withPatFailMsg (wrongExprForm "abs (rep a)") $+           do App abs' (App rep' a) <- idR+              guardMsg (exprAlphaEq abs abs') "given wrapper does not match wrapper in expression."+              guardMsg (exprAlphaEq rep rep') "given unwrapper does not match unwrapper in expression."+              return a++    wwAR :: Type -> RewriteH CoreExpr+    wwAR tyA = do a <- idR+                  guardMsg (exprKindOrType a `eqType` tyA) "type of expression does not match types of abs/rep."+                  return $ App abs (App rep a)++-- | @abs (rep a)@  \<==\>  @a@+wwA :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption A+    -> CoreString                -- ^ abs+    -> CoreString                -- ^ rep+    -> BiRewriteH CoreExpr+wwA mr = parse2beforeBiR (wwResultAssA mr)++-- | @abs (rep (f h x))@  \<==\>  @f h x@+wwResultAssB :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption B+       -> CoreExpr                  -- ^ abs+       -> CoreExpr                  -- ^ rep+       -> CoreExpr                  -- ^ f+       -> BiRewriteH CoreExpr+wwResultAssB mr abs rep f = beforeBiR (whenJust (verifyAssB abs rep f) mr)+                                (\ () -> bidirectional wwBL wwBR)+  where+    assA :: BiRewriteH CoreExpr+    assA = wwResultAssA Nothing abs rep++    wwBL :: RewriteH CoreExpr+    wwBL = withPatFailMsg (wrongExprForm "abs (rep (f h x))") $+           do App _ (App _ (App (App f' _) _)) <- idR+              guardMsg (exprAlphaEq f f') "given body function does not match expression."+              forwardT assA++    wwBR :: RewriteH CoreExpr+    wwBR = withPatFailMsg (wrongExprForm "f h x") $+           do App (App f' _) _ <- idR+              guardMsg (exprAlphaEq f f') "given body function does not match expression."+              backwardT assA++-- | @abs (rep (f h x))@  \<==\>  @f h x@+wwB :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption B+    -> CoreString                -- ^ abs+    -> CoreString                -- ^ rep+    -> CoreString                -- ^ f+    -> BiRewriteH CoreExpr+wwB mr = parse3beforeBiR (wwResultAssB mr)++-- | @fix (X->A) (\ h x -> abs (rep (f h x)))@  \<==\>  @fix (X->A) f@+wwResultAssC :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption C+       -> CoreExpr                  -- ^ abs+       -> CoreExpr                  -- ^ rep+       -> CoreExpr                  -- ^ f+       -> BiRewriteH CoreExpr+wwResultAssC mr abs rep f = beforeBiR (do _ <- isFixExprT+                                          whenJust (verifyAssC abs rep f) mr+                                      )+                                      (\ () -> bidirectional wwCL wwCR)+  where+    assB :: BiRewriteH CoreExpr+    assB = wwResultAssB Nothing abs rep f++    wwCL :: RewriteH CoreExpr+    wwCL = wwResultAssAimpliesAssC (forwardT assB)++    wwCR :: RewriteH CoreExpr+    wwCR = appAllR idR (etaExpandR "h" >>> lamAllR idR (etaExpandR "x" >>> lamAllR idR (backwardT assB)))++-- | @fix (X->A) (\ h x -> abs (rep (f h x)))@  \<==\>  @fix (X->A) f@+wwC :: Maybe (RewriteH CoreExpr) -- ^ WW Assumption C+    -> CoreString                -- ^ abs+    -> CoreString                -- ^ rep+    -> CoreString                -- ^ f+    -> BiRewriteH CoreExpr+wwC mr = parse3beforeBiR (wwResultAssC mr)++--------------------------------------------------------------------------------------------------++verifyWWAss :: CoreExpr        -- ^ abs+            -> CoreExpr        -- ^ rep+            -> CoreExpr        -- ^ f+            -> WWAssumption+            -> TranslateH x ()+verifyWWAss abs rep f (WWAssumption tag ass) =+    case tag of+      A -> verifyAssA abs rep ass+      B -> verifyAssB abs rep f ass+      C -> verifyAssC abs rep f ass++verifyAssA :: CoreExpr          -- ^ abs+           -> CoreExpr          -- ^ rep+           -> RewriteH CoreExpr -- ^ WW Assumption A+           -> TranslateH x ()+verifyAssA abs rep assA =+  prefixFailMsg ("verification of worker/wrapper Assumption A failed: ") $+  do _ <- absRepTypes abs rep  -- this check is redundant, but will produce a better error message+     verifyRetractionT abs rep assA++verifyAssB :: CoreExpr          -- ^ abs+           -> CoreExpr          -- ^ rep+           -> CoreExpr          -- ^ f+           -> RewriteH CoreExpr -- ^ WW Assumption B+           -> TranslateH x ()+verifyAssB abs rep f assB =+  prefixFailMsg ("verification of worker/wrapper assumption B failed: ") $+  do (tyA,_) <- absRepTypes abs rep+     tyXA     <- constT (endoFunType f)+     (tyX,tA) <- constT (splitFunTypeM tyXA)+     guardMsg (eqType tyA tA) "type of program body does not match types of abs/rep."+     h        <- constT (newIdH "h" tyXA)+     x        <- constT (newIdH "x" tyX)+     let lhs = App abs (App rep (App (App f (Var h)) (Var x)))+         rhs = App (App f (Var h)) (Var x)+     verifyEqualityLeftToRightT lhs rhs assB++verifyAssC :: CoreExpr          -- ^ abs+           -> CoreExpr          -- ^ rep+           -> CoreExpr          -- ^ f+           -> RewriteH CoreExpr -- ^ WW Assumption C+           -> TranslateH a ()+verifyAssC abs rep f assC =+  prefixFailMsg ("verification of worker/wrapper assumption C failed: ") $+  do (tyA,_)  <- absRepTypes abs rep+     tyXA     <- constT (endoFunType f)+     (tyX,tA) <- constT (splitFunTypeM tyXA)+     guardMsg (eqType tyA tA) "type of program body does not match types of abs/rep."+     h        <- constT (newIdH "h" tyXA)+     x        <- constT (newIdH "x" tyX)+     rhs      <- mkFixT f+     lhs      <- mkFixT (Lam h (Lam x (App abs (App rep (App (App f (Var h)) (Var x))))))+     verifyEqualityLeftToRightT lhs rhs assC++--------------------------------------------------------------------------------------------------++absRepTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type,Type)+absRepTypes abs rep = setFailMsg "given expressions have the wrong types to form a valid abs/rep pair." $+                      funsWithInverseTypes rep abs++--------------------------------------------------------------------------------------------------
+ src/HERMIT/External.hs view
@@ -0,0 +1,474 @@+{-# LANGUAGE GADTs, TypeFamilies, FlexibleContexts, FlexibleInstances, DeriveDataTypeable #-}++module HERMIT.External+       (+       -- * Externals+         External+       , ExternalName+       , ExternalHelp+       , externName+       , externDyn+       , externHelp+       , Dictionary+       , toDictionary+       , toHelp+       , external+       , Extern(..)+       , matchingExternals+       -- * Tags+       , CmdTag(..)+       , TagE+       , Tag((.+),remTag,tagMatch)+       , (.&)+       , (.||)+       , notT+       , externTags+       , dictionaryOfTags+       -- * Boxes+       -- | Boxes are used by the 'Extern' class.+       , TagBox(..)+       , IntBox(..)+       , RewriteCoreBox(..)+       , RewriteCoreTCBox(..)+       , BiRewriteCoreBox(..)+       , TranslateCoreStringBox(..)+       , TranslateCoreTCStringBox(..)+       , TranslateCoreCheckBox(..)+       , TranslateCoreTCCheckBox(..)+       , TranslateCorePathBox(..)+       , TranslateCoreTCPathBox(..)+       , NameBox(..)+       , CoreString(..)+       , CoreBox(..)+       , CrumbBox(..)+       , PathBox(..)+       , StringBox(..)+       , NameListBox(..)+       , StringListBox(..)+       , IntListBox(..)+       , RewriteCoreListBox(..)+) where++import Data.Map hiding (map)+import Data.Dynamic+import Data.List++import qualified Language.Haskell.TH as TH++import HERMIT.Core+import HERMIT.Context (LocalPathH)+import HERMIT.Kure++-----------------------------------------------------------------++-- | 'External' names are just strings.+type ExternalName = String++-- | Help information for 'External's is stored as a list of strings, designed for multi-line displaying.+type ExternalHelp = [String]++-- Tags --------------------------------------------------------++-- | Requirement: commands cannot have the same name as any 'CmdTag'+--   (or the help function will not find it).+--   These should be /user facing/, because they give the user+--   a way of sub-dividing our confusing array of commands.+data CmdTag = Shell          -- ^ Shell-specific command.+            | Eval           -- ^ The arrow of evaluation (reduces a term).+            | KURE           -- ^ 'Language.KURE' command.+            | Loop           -- ^ Command may operate multiple times.+            | Deep           -- ^ Command may make a deep change, can be O(n).+            | Shallow        -- ^ Command operates on local nodes only, O(1).+            | Navigation     -- ^ Uses 'Path' or 'Lens' to focus onto something.+            | Query          -- ^ A question we ask.+            | Predicate      -- ^ Something that passes or fails.+            | Introduce      -- ^ Introduce something, like a new name.+            | Commute        -- ^ Commute is when you swap nested terms.+            | PreCondition   -- ^ Operation has a (perhaps undocumented) precondition.+            | Debug          -- ^ Commands specifically to help debugging.+            | VersionControl -- ^ Version control for Core syntax.+            | Context        -- ^ A command that uses its context, such as inlining.+            | Unsafe         -- ^ Commands that are not type safe (may cause Core Lint to fail),+                             --   or may otherwise change the semantics of the program.++            | TODO           -- ^ An incomplete or potentially buggy command.+            | Experiment     -- ^ Things we are trying out.+            | Deprecated     -- ^ A command that will be removed in a future release;+                             --   it has probably been renamed or subsumed by another command.+++-- Unsure about these+{-+            | Local         -- local thing, O(1)+            | CaseCmd       -- works on case statements+            | Context       -- something that uses the context+            | GHC           -- a tunnel into GHC+            | Lens          -- focuses into a specific node+            | LetCmd        -- works on let statements+            | Meta          -- combines other commands+            | Restful       -- RESTful API commands+            | Slow          -- this command is slow+-}+            -- Other String+            -- etc+    deriving (Eq, Show, Read, Bounded, Enum)++-- | Lists all the tags paired with a short description of what they're about.+dictionaryOfTags :: [(CmdTag,String)]+dictionaryOfTags = notes ++ [ (tag,"(unknown purpose)")+                            | tag <- [minBound..maxBound]+                            , tag `notElem` map fst notes+                            ]+  where notes =+          -- These should give the user a clue about what the sub-commands+          -- might do+          [ (Shell,        "Shell-specific command.")+          , (Eval,         "The arrow of evaluation (reduces a term).")+          , (KURE,         "Direct reflection of a combinator from the KURE DSL.")+          , (Loop,         "Command may operate multiple times.")+          , (Deep,         "Command may make a deep change, can be O(n).")+          , (Shallow,      "Command operates on local nodes only, O(1).")+          , (Navigation,   "Navigate via focus, or directional command.")+          , (Query,        "A question we ask.")+          , (Predicate,    "Something that passes or fails.")+          , (Introduce,    "Introduce something, like a new name.")+          , (Commute,      "Commute is when you swap nested terms.")+          , (PreCondition, "Operation has a (perhaps undocumented) precondition.")+          , (Debug,        "A command specifically to help debugging.")+          , (VersionControl,"Version control for Core syntax.")+          , (Context,      "A command that uses its context, such as inlining.")+          , (Unsafe,       "Commands that are not type safe (may cause Core Lint to fail), or may otherwise change the semantics of the program.")+          , (TODO,         "An incomplete or potentially buggy command.")+          , (Experiment,   "Things we are trying out, use at your own risk.")+          , (Deprecated,   "A command that will be removed in a future release; it has probably been renamed or subsumed by another command.")+          ]+++-- Unfortunately, record update syntax seems to associate to the right.+-- These operators save us some parentheses.+infixl 3 .++infixr 4 .||+infixr 5 .&++-- | A data type of logical operations on tags.+data TagE :: * where+    Tag    :: Tag a => a -> TagE+    NotTag :: TagE -> TagE+    AndTag :: TagE -> TagE -> TagE+    OrTag  :: TagE -> TagE -> TagE++-- | Tags are meta-data that we add to 'External's to make them sortable and searchable.+class Tag a where+    toTagE :: a -> TagE++    -- | Add a 'Tag' to an 'External'.+    (.+) :: External -> a -> External++    -- | Remove a 'Tag' from an 'External'.+    remTag :: a -> External -> External++    -- | Check if an 'External' has the specified 'Tag'.+    tagMatch :: a -> External -> Bool++instance Tag TagE where+    toTagE = id++    e .+ (Tag t) = e .+ t+    e .+ (NotTag t) = remTag t e+    e .+ (AndTag t1 t2) = e .+ t1 .+ t2+    e .+ (OrTag t1 t2) = e .+ t1 .+ t2 -- not sure what else to do++    remTag (Tag t) e = remTag t e+    remTag (NotTag t) e = e .+ t+    remTag (AndTag t1 t2) e = remTag t1 (remTag t2 e)+    remTag (OrTag t1 t2) e = remTag t1 (remTag t2 e) -- again++    tagMatch (Tag t)        e = tagMatch t e+    tagMatch (NotTag t)     e = not (tagMatch t e)+    tagMatch (AndTag t1 t2) e = tagMatch t1 e && tagMatch t2 e+    tagMatch (OrTag  t1 t2) e = tagMatch t1 e || tagMatch t2 e++instance Tag CmdTag where+    toTagE = Tag+    ex@(External {externTags = ts}) .+ t = ex {externTags = t:ts}+    remTag t ex@(External {externTags = ts}) = ex { externTags = [ t' | t' <- ts, t' /= t ] }+    tagMatch t (External {externTags = ts}) = t `elem` ts++-- | An \"and\" on 'Tag's.+(.&) :: (Tag a, Tag b) => a -> b -> TagE+t1 .& t2 = AndTag (toTagE t1) (toTagE t2)++-- | An \"or\" on 'Tag's.+(.||) :: (Tag a, Tag b) => a -> b -> TagE+t1 .|| t2 = OrTag (toTagE t1) (toTagE t2)++-- how to make a unary operator?+-- | A \"not\" on 'Tag's.+notT :: Tag a => a -> TagE+notT = NotTag . toTagE++-----------------------------------------------------------------++-- | An 'External' is a 'Dynamic' value with some associated meta-data (name, help string and tags).+data External = External+        { externName :: ExternalName        -- ^ Get the name of an 'External'.+        , externDyn  :: Dynamic             -- ^ Get the 'Dynamic' value stored in an 'External'.+        , externHelp :: ExternalHelp        -- ^ Get the list of help 'String's for an 'External'.+        , externTags :: [CmdTag]            -- ^ List all the 'CmdTag's associated with an 'External'+        }++-- | The primitive way to build an 'External'.+external :: Extern a => ExternalName -> a -> ExternalHelp -> External+external nm fn help = External+        { externName = nm+        , externDyn  = toDyn (box fn)+        , externHelp = map ("  " ++) help+        , externTags = []+        }++-- | Get all the 'External's which match a given tag predicate+-- and box a Translate of the appropriate type.+matchingExternals :: (Extern tr, Tag t) => t -> [External] -> [(External, tr)]+matchingExternals tag exts = [ (e,tr) | e <- exts, tagMatch tag e+                                      , Just tr <- [fmap unbox $ fromDynamic $ externDyn e] ]++-- | A 'Dictionary' is a collection of 'Dynamic's.+--   Looking up a 'Dynamic' (via an 'ExternalName' key) returns a list, as there can be multiple 'Dynamic's with the same name.+type Dictionary = Map ExternalName [Dynamic]++-- | Build a 'Data.Map' from names to 'Dynamic' values.+toDictionary :: [External] -> Dictionary+toDictionary+        -- TODO: check names are uniquely-prefixed+              = fromListWith (++) . map toD+  where+         toD :: External -> (ExternalName,[Dynamic])+         toD e = (externName e,[externDyn e])++-- | Build a 'Data.Map' from names to help information.+toHelp :: [External] -> Map ExternalName ExternalHelp+toHelp = fromListWith (++) . map toH+  where+         toH :: External -> (ExternalName,ExternalHelp)+         toH e = (externName e, spaceout (externName e ++ " :: " ++ fixup (show (dynTypeRep (externDyn e))))+                                         (show (externTags e)) : externHelp e)++         spaceout xs ys = xs ++ replicate (width - (length xs + length ys)) ' ' ++ ys++         width = 78++         fixup :: String -> String+         fixup xs | "Box" `isPrefixOf` xs = fixup (drop 3 xs)+         fixup (x:xs)                     = x : fixup xs+         fixup []                         = []+++-----------------------------------------------------------------++-- | The class of things that can be made into 'External's.+--   To be an 'Extern' there must exist an isomorphic 'Box' type that is an instance of 'Typeable'.+class Typeable (Box a) => Extern a where++    -- | An isomorphic wrapper.+    type Box a++    -- | Wrap a value in a 'Box'.+    box :: a -> Box a++    -- | Unwrap a value from a 'Box'.+    unbox :: Box a -> a++-----------------------------------------------------------------++instance (Extern a, Extern b) => Extern (a -> b) where+    type Box (a -> b) = Box a -> Box b+    box f = box . f . unbox+    unbox f = unbox . f . box++-----------------------------------------------------------------++data TagBox = TagBox TagE deriving Typeable++instance Extern TagE where+    type Box TagE = TagBox+    box = TagBox+    unbox (TagBox t) = t++-----------------------------------------------------------------++data IntBox = IntBox Int deriving Typeable++instance Extern Int where+    type Box Int = IntBox+    box = IntBox+    unbox (IntBox i) = i++-----------------------------------------------------------------++data RewriteCoreBox = RewriteCoreBox (RewriteH Core) deriving Typeable++instance Extern (RewriteH Core) where+    type Box (RewriteH Core) = RewriteCoreBox+    box = RewriteCoreBox+    unbox (RewriteCoreBox r) = r++-----------------------------------------------------------------++data RewriteCoreTCBox = RewriteCoreTCBox (RewriteH CoreTC) deriving Typeable++instance Extern (RewriteH CoreTC) where+    type Box (RewriteH CoreTC) = RewriteCoreTCBox+    box = RewriteCoreTCBox+    unbox (RewriteCoreTCBox r) = r++-----------------------------------------------------------------++data BiRewriteCoreBox = BiRewriteCoreBox (BiRewriteH Core) deriving Typeable++instance Extern (BiRewriteH Core) where+    type Box (BiRewriteH Core) = BiRewriteCoreBox+    box = BiRewriteCoreBox+    unbox (BiRewriteCoreBox b) = b++-----------------------------------------------------------------++data TranslateCoreTCStringBox = TranslateCoreTCStringBox (TranslateH CoreTC String) deriving Typeable++instance Extern (TranslateH CoreTC String) where+    type Box (TranslateH CoreTC String) = TranslateCoreTCStringBox+    box = TranslateCoreTCStringBox+    unbox (TranslateCoreTCStringBox t) = t++-----------------------------------------------------------------++data TranslateCoreStringBox = TranslateCoreStringBox (TranslateH Core String) deriving Typeable++instance Extern (TranslateH Core String) where+    type Box (TranslateH Core String) = TranslateCoreStringBox+    box = TranslateCoreStringBox+    unbox (TranslateCoreStringBox t) = t++-----------------------------------------------------------------++data TranslateCoreTCCheckBox = TranslateCoreTCCheckBox (TranslateH CoreTC ()) deriving Typeable++instance Extern (TranslateH CoreTC ()) where+    type Box (TranslateH CoreTC ()) = TranslateCoreTCCheckBox+    box = TranslateCoreTCCheckBox+    unbox (TranslateCoreTCCheckBox t) = t++-----------------------------------------------------------------++data TranslateCoreCheckBox = TranslateCoreCheckBox (TranslateH Core ()) deriving Typeable++instance Extern (TranslateH Core ()) where+    type Box (TranslateH Core ()) = TranslateCoreCheckBox+    box = TranslateCoreCheckBox+    unbox (TranslateCoreCheckBox t) = t++-----------------------------------------------------------------++data NameBox = NameBox (TH.Name) deriving Typeable++instance Extern TH.Name where+    type Box TH.Name = NameBox+    box = NameBox+    unbox (NameBox n) = n++-----------------------------------------------------------------++-- TODO: We now have CrumbBoc, PathBox and TranslateCorePathBox.+--       Ints are interpreted as a TranslateCorePathBox.+--       This all needs cleaning up.++data CrumbBox = CrumbBox Crumb deriving Typeable++instance Extern Crumb where+    type Box Crumb = CrumbBox+    box = CrumbBox+    unbox (CrumbBox cr) = cr++-----------------------------------------------------------------++data PathBox = PathBox LocalPathH deriving Typeable++instance Extern LocalPathH where+    type Box LocalPathH = PathBox+    box = PathBox+    unbox (PathBox p) = p++-----------------------------------------------------------------++data TranslateCorePathBox = TranslateCorePathBox (TranslateH Core LocalPathH) deriving Typeable++instance Extern (TranslateH Core LocalPathH) where+    type Box (TranslateH Core LocalPathH) = TranslateCorePathBox+    box = TranslateCorePathBox+    unbox (TranslateCorePathBox t) = t++-----------------------------------------------------------------++data TranslateCoreTCPathBox = TranslateCoreTCPathBox (TranslateH CoreTC LocalPathH) deriving Typeable++instance Extern (TranslateH CoreTC LocalPathH) where+    type Box (TranslateH CoreTC LocalPathH) = TranslateCoreTCPathBox+    box = TranslateCoreTCPathBox+    unbox (TranslateCoreTCPathBox t) = t++-----------------------------------------------------------------++-- TODO: Is this deliberately called "CoreBox" rather than "CoreStringBox"?+newtype CoreString = CoreString { unCoreString :: String }+data CoreBox = CoreBox CoreString deriving Typeable++instance Extern CoreString where+    type Box CoreString = CoreBox+    box = CoreBox+    unbox (CoreBox s) = s++-----------------------------------------------------------------++data StringBox = StringBox String deriving Typeable++instance Extern String where+    type Box String = StringBox+    box = StringBox+    unbox (StringBox s) = s++-----------------------------------------------------------------++data NameListBox = NameListBox [TH.Name] deriving Typeable++instance Extern [TH.Name] where+    type Box [TH.Name] = NameListBox+    box = NameListBox+    unbox (NameListBox l) = l++-----------------------------------------------------------------++data StringListBox = StringListBox [String] deriving Typeable++instance Extern [String] where+    type Box [String] = StringListBox+    box = StringListBox+    unbox (StringListBox l) = l++-----------------------------------------------------------------++data IntListBox = IntListBox [Int] deriving Typeable++instance Extern [Int] where+    type Box [Int] = IntListBox+    box = IntListBox+    unbox (IntListBox l) = l++-----------------------------------------------------------------++data RewriteCoreListBox = RewriteCoreListBox [RewriteH Core] deriving Typeable++instance Extern [RewriteH Core] where+    type Box [RewriteH Core] = RewriteCoreListBox+    box = RewriteCoreListBox+    unbox (RewriteCoreListBox l) = l++-----------------------------------------------------------------
+ src/HERMIT/GHC.hs view
@@ -0,0 +1,227 @@+{-# LANGUAGE CPP, InstanceSigs, TypeSynonymInstances, FlexibleInstances #-}+module HERMIT.GHC+    ( -- * GHC Imports+      -- | Things that have been copied from GHC, or imported directly, for various reasons.+      module GhcPlugins+    , ppIdInfo+    , zapVarOccInfo+    , var2String+    , thRdrNameGuesses+    , name2THName+    , var2THName+    , cmpTHName2Name+    , cmpString2Name+    , cmpTHName2Var+    , cmpString2Var+    , fqName+    , uqName+    , findNamesFromString+    , findNamesFromTH+    , alphaTyVars+    , Type(..)+    , TyLit(..)+    , GhcException(..)+    , throwGhcException+    , exprArity+    , occurAnalyseExpr+    , isKind+    , isLiftedTypeKindCon+#if __GLASGOW_HASKELL__ > 706+    , coAxiomName+    , CoAxiom.BranchIndex+    , CoAxiom.CoAxiom+    , CoAxiom.Branched+#endif+    , notElemVarSet+    , varSetToStrings+    , showVarSet+    , Pair(..)+#if __GLASGOW_HASKELL__ <= 706+    , Control.Monad.IO.Class.liftIO+#endif+    ) where++#if __GLASGOW_HASKELL__ <= 706+import qualified Control.Monad.IO.Class+import qualified MonadUtils (MonadIO,liftIO)+import GhcPlugins hiding (exprFreeVars, exprFreeIds, bindFreeVars, liftIO)+#else+import GhcPlugins hiding (exprFreeVars, exprFreeIds, bindFreeVars) -- we hide these so that they don't get inadvertently used.  See Core.hs+#endif++-- hacky direct GHC imports+import Convert (thRdrNameGuesses)+import TysPrim (alphaTyVars)+import TypeRep (Type(..),TyLit(..))+import Panic (GhcException(ProgramError), throwGhcException)+import CoreArity+import Kind (isKind,isLiftedTypeKindCon)+import OccurAnal (occurAnalyseExpr)+import Pair (Pair(..))++#if __GLASGOW_HASKELL__ <= 706+import Data.Maybe (isJust)+#else+import qualified CoAxiom -- for coAxiomName+#endif+import Data.List (intercalate)+import Data.Monoid hiding ((<>))+import qualified Language.Haskell.TH as TH++--------------------------------------------------------------------------++-- | Convert a 'VarSet' to a list of user-readable strings.+varSetToStrings :: VarSet -> [String]+varSetToStrings = map var2String . varSetElems++-- | Show a human-readable version of a 'VarSet'.+showVarSet :: VarSet -> String+showVarSet = intercalate ", " . varSetToStrings++--------------------------------------------------------------------------++#if __GLASGOW_HASKELL__ <= 706+-- coAxiomName :: CoAxiom -> Name+-- coAxiomName = coAxiomName+#else+coAxiomName :: CoAxiom.CoAxiom br -> Name+coAxiomName = CoAxiom.coAxiomName+#endif++-- varName :: Var -> Name+-- nameOccName :: Name -> OccName+-- occNameString :: OccName -> String+-- getOccName :: NamedThing a => a -> OccName+-- getName :: NamedThing a => a -> Name+-- getOccString :: NamedThing a => a -> String++-- TH.nameBase :: TH.Name -> String+-- showName :: TH.Name -> String+-- TH.mkName :: String -> TH.Name++-- | Get the unqualified name from a 'NamedThing'.+uqName :: NamedThing nm => nm -> String+uqName = getOccString++-- | Get the fully qualified name from a 'Name'.+fqName :: Name -> String+fqName nm = modStr ++ uqName nm+    where modStr = maybe "" (\m -> moduleNameString (moduleName m) ++ ".") (nameModule_maybe nm)++-- | Convert a variable to a neat string for printing (unqualfied name).+var2String :: Var -> String+var2String = uqName . varName++-- | Converts a GHC 'Name' to a Template Haskell 'TH.Name', going via a 'String'.+name2THName :: Name -> TH.Name+name2THName = TH.mkName . uqName++-- | Converts an 'Var' to a Template Haskell 'TH.Name', going via a 'String'.+var2THName :: Var -> TH.Name+var2THName = name2THName . varName++-- | Compare a 'String' to a 'Name' for equality.+-- Strings containing a period are assumed to be fully qualified names.+cmpString2Name :: String -> Name -> Bool+cmpString2Name str nm | isQualified str = str == fqName nm+                      | otherwise       = str == uqName nm++isQualified :: String -> Bool+isQualified [] = False+isQualified xs = '.' `elem` init xs -- pathological case is compose++-- | Compare a 'String' to a 'Var' for equality. See 'cmpString2Name'.+cmpString2Var :: String -> Var -> Bool+cmpString2Var str = cmpString2Name str . varName++-- | Compare a 'TH.Name' to a 'Name' for equality. See 'cmpString2Name'.+cmpTHName2Name :: TH.Name -> Name -> Bool+cmpTHName2Name th_nm = cmpString2Name (show th_nm)++-- | Compare a 'TH.Name' to a 'Var' for equality. See 'cmpString2Name'.+cmpTHName2Var :: TH.Name -> Var -> Bool+cmpTHName2Var nm = cmpTHName2Name nm . varName++-- | Find 'Name's matching a given fully qualified or unqualified name.+-- If given name is fully qualified, will only return first result, which is assumed unique.+findNamesFromString :: GlobalRdrEnv -> String -> [Name]+findNamesFromString rdrEnv str | isQualified str = take 1 res+                               | otherwise       = res+    where res = [ nm | elt <- globalRdrEnvElts rdrEnv, let nm = gre_name elt, cmpString2Name str nm ]++-- | Find 'Name's matching a 'TH.Name'. See 'findNamesFromString'.+findNamesFromTH :: GlobalRdrEnv -> TH.Name -> [Name]+findNamesFromTH rdrEnv = findNamesFromString rdrEnv . show++-- | Pretty-print an identifier.+ppIdInfo :: Id -> IdInfo -> SDoc+ppIdInfo v info+  = showAttributes+    [ (True, pp_scope <> ppr (idDetails v))+    , (has_arity,      ptext (sLit "Arity=") <> int arity)+    , (has_caf_info,   ptext (sLit "Caf=") <> ppr caf_info)+    , (has_strictness, ptext (sLit "Str=") <> pprStrictness str_info)+    , (has_unf,        ptext (sLit "Unf=") <> ppr unf_info)+    , (notNull rules,  ptext (sLit "RULES:") <+> vcat (map ppr rules))+    ]	-- Inline pragma, occ, demand, lbvar info+	-- printed out with all binders (when debug is on);+	-- see PprCore.pprIdBndr+  where+    pp_scope | isGlobalId v   = ptext (sLit "GblId")+    	     | isExportedId v = ptext (sLit "LclIdX")+    	     | otherwise      = ptext (sLit "LclId")++    arity = arityInfo info+    has_arity = arity /= 0++    caf_info = cafInfo info+    has_caf_info = not (mayHaveCafRefs caf_info)++    str_info = strictnessInfo info+    has_strictness =+#if __GLASGOW_HASKELL__ > 706+        True+#else+        isJust str_info+#endif++    unf_info = unfoldingInfo info+    has_unf = hasSomeUnfolding unf_info++    rules = specInfoRules (specInfo info)++showAttributes :: [(Bool,SDoc)] -> SDoc+showAttributes stuff+  | null docs = empty+  | otherwise = brackets (sep (punctuate comma docs))+  where+    docs = [d | (True,d) <- stuff]++-- | Erase all 'OccInfo' in a variable if it is is an 'Id', or do nothing if it's a 'TyVar' or 'CoVar' (which have no 'OccInfo').+zapVarOccInfo :: Var -> Var+zapVarOccInfo i = if isId i+                    then zapIdOccInfo i+                    else i++--------------------------------------------------------------------------++-- | Determine if a 'Var' is not an element of a 'VarSet'.+notElemVarSet :: Var -> VarSet -> Bool+notElemVarSet v vs = not (v `elemVarSet` vs)++instance Monoid VarSet where+  mempty :: VarSet+  mempty = emptyVarSet++  mappend :: VarSet -> VarSet -> VarSet+  mappend = unionVarSet++--------------------------------------------------------------------------++#if __GLASGOW_HASKELL__ <= 706+instance Control.Monad.IO.Class.MonadIO CoreM where+  liftIO :: IO a -> CoreM a+  liftIO = MonadUtils.liftIO+#endif++--------------------------------------------------------------------------
+ src/HERMIT/Interp.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE KindSignatures, GADTs, InstanceSigs #-}++module HERMIT.Interp+        ( -- * The HERMIT Interpreter+          Interp+        , interp+        , interpExprH+        ) where++import Control.Monad (liftM, liftM2)++import Data.Char+import Data.Dynamic+import qualified Data.Map as M++import qualified Language.Haskell.TH as TH++import HERMIT.External+import HERMIT.Parser+import HERMIT.Kure (deprecatedIntToPathT,pathToSnocPath)++-- | Interpret an 'ExprH' by looking up the appropriate 'Dynamic'(s) in the provided 'Dictionary', then interpreting the 'Dynamic'(s) with the provided 'Interp's, returning the first interpretation to succeed (or an error string if none succeed).+interpExprH :: Monad m => Dictionary -> [Interp a] -> ExprH -> m a+interpExprH dict interps e = do dyns <- interpExpr dict e+                                runInterp dyns interps++runInterp :: Monad m => [Dynamic] -> [Interp b] -> m b+runInterp dyns interps = case [f a | Interp f <- interps, Just a <- map fromDynamic dyns] of+                           []  -> fail "User error, HERMIT command does not type-check."+                           b:_ -> return b++-- | An 'Interp' @a@ is a /possible/ means of converting a 'Typeable' value to a value of type @a@.+data Interp :: * -> * where+   Interp :: Typeable a => (a -> b) -> Interp b++-- | The primitive way of building an 'Interp'.+interp :: Typeable a => (a -> b) -> Interp b+interp = Interp++instance Functor Interp where+  fmap :: (a -> b) -> Interp a -> Interp b+  fmap f (Interp g) = Interp (f . g)+++interpExpr :: Monad m => Dictionary -> ExprH -> m [Dynamic]+interpExpr = interpExpr' False++-- input: list length n, each elem is a variable length list of possible interpretations+-- output: variable length list, each elem is list of length n+fromDynList :: [[Dynamic]] -> [[Dynamic]]+fromDynList [] = [[]]+fromDynList (hs:dynss) = [ h:t | h <- hs, t <- fromDynList dynss ]++toBoxedList :: (Extern a, Typeable b) => [[Dynamic]] -> ([a] -> b) -> [Dynamic]+toBoxedList dyns boxCon = [ toDyn $ boxCon (map unbox l) | dl <- dyns, Just l <- [mapM fromDynamic dl] ]++interpExpr' :: Monad m => Bool -> Dictionary -> ExprH -> m [Dynamic]+interpExpr' _   _    (SrcName str) = return [ toDyn $ NameBox $ TH.mkName str ]+interpExpr' _   _    (CoreH str)   = return [ toDyn $ CoreBox (CoreString str) ]+interpExpr' _   dict (ListH exprs) = do dyns <- liftM fromDynList $ mapM (interpExpr' True dict) exprs+                                        return $    toBoxedList dyns NameListBox+                                                 ++ toBoxedList dyns StringListBox+                                                 ++ toBoxedList dyns (PathBox . pathToSnocPath)+                                                 ++ toBoxedList dyns (TranslateCorePathBox . return . pathToSnocPath) -- ugly hack.  The whole dynamic stuff could do with overhauling.+                                                 ++ toBoxedList dyns IntListBox+                                                 ++ toBoxedList dyns RewriteCoreListBox+interpExpr' rhs dict (CmdName str)+                                        -- An Int is either a Path, or will be interpreted specially later.+  | all isDigit str                     = let i = read str in+                                          return [ toDyn $ IntBox i+                                                 , toDyn $ TranslateCorePathBox (deprecatedIntToPathT i) -- TODO: Find a better long-term solution.+                                                 ]+  | Just dyn <- M.lookup str dict       = return $ if rhs+                                                     then toDyn (StringBox str) : dyn+                                                     else dyn+  -- not a command, try as a string arg... worst case: dynApply fails with "bad type of expression"+  -- best case: 'help ls' works instead of 'help "ls"'. this is likewise done in the clause above+  | rhs                                 = return [toDyn $ StringBox str]+  | otherwise                           = fail $ "User error, unrecognised HERMIT command: " ++ show str+interpExpr' _ env (AppH e1 e2)          = dynAppMsg (interpExpr' False env e1) (interpExpr' True env e2)++dynAppMsg :: Monad m => m [Dynamic] -> m [Dynamic] -> m [Dynamic]+dynAppMsg = liftM2 dynApply'+   where+           dynApply' :: [Dynamic] -> [Dynamic] -> [Dynamic]+           dynApply' fs xs = [ r | f <- fs, x <- xs, Just r <- return (dynApply f x)]++-------------------------------------------
+ src/HERMIT/Kernel.hs view
@@ -0,0 +1,120 @@+{-# LANGUAGE RankNTypes, ScopedTypeVariables, TupleSections, GADTs #-}++module HERMIT.Kernel+        ( -- * The HERMIT Kernel+          AST+        , Kernel+        , hermitKernel+        , resumeK+        , abortK+        , applyK+        , queryK+        , deleteK+        , listK+) where++import Prelude hiding (lookup)++import HERMIT.Context+import HERMIT.Monad+import HERMIT.Kure+import HERMIT.GHC hiding (singleton, empty)++import Data.Map+import Control.Concurrent++-- | A 'Kernel' is a repository for complete Core syntax trees ('ModGuts').+--   For now, operations on a 'Kernel' are sequential, but later+--   it will be possible to have two 'applyK's running in parallel.+data Kernel = Kernel+  { resumeK ::            AST                                        -> IO ()           -- ^ Halt the 'Kernel' and return control to GHC, which compiles the specified 'AST'.+  , abortK  ::                                                          IO ()           -- ^ Halt the 'Kernel' and abort GHC without compiling.+  , applyK  ::            AST -> RewriteH ModGuts     -> HermitMEnv  -> IO (KureM AST)  -- ^ Apply a 'Rewrite' to the specified 'AST' and return a handle to the resulting 'AST'.+  , queryK  :: forall a . AST -> TranslateH ModGuts a -> HermitMEnv  -> IO (KureM a)    -- ^ Apply a 'TranslateH' to the 'AST' and return the resulting value.+  , deleteK ::            AST                                        -> IO ()           -- ^ Delete the internal record of the specified 'AST'.+  , listK   ::                                                          IO [AST]        -- ^ List all the 'AST's tracked by the 'Kernel'.+  }++-- | A /handle/ for a specific version of the 'ModGuts'.+newtype AST = AST Int -- ^ Currently 'AST's are identified by an 'Int' label.+              deriving (Eq, Ord, Show)++data Msg s r = forall a . Req (s -> CoreM (KureM (a,s))) (MVar (KureM a))+             | Done (s -> CoreM r)++type KernelState = Map AST (DefStash, ModGuts)++-- | Start a HERMIT client by providing an IO function that takes the initial 'Kernel' and inital 'AST' handle.+--   The 'Modguts' to 'CoreM' Modguts' function required by GHC Plugins is returned.+--   The callback is only ever called once.+hermitKernel :: (Kernel -> AST -> IO ()) -> ModGuts -> CoreM ModGuts+hermitKernel callback modGuts = do++        msgMV :: MVar (Msg KernelState ModGuts) <- liftIO newEmptyMVar++        nextASTname :: MVar AST <- liftIO newEmptyMVar++        _ <- liftIO $ forkIO $ let loop n = do putMVar nextASTname (AST n)+                                               loop (succ n)+                                in loop 0++        let sendDone :: (KernelState -> CoreM ModGuts) -> IO ()+            sendDone = putMVar msgMV . Done++        let sendReq :: (KernelState -> CoreM (KureM (a, KernelState))) -> IO (KureM a)+            sendReq fn = do rep  <- newEmptyMVar+                            putMVar msgMV (Req fn rep)+                            takeMVar rep++        let sendReqRead :: (KernelState -> CoreM (KureM a)) -> IO (KureM a)+            sendReqRead fn = sendReq (\ st -> (fmap.fmap) (,st) $ fn st)++        let sendReqWrite :: (KernelState -> CoreM KernelState) -> IO ()+            sendReqWrite fn = sendReq (fmap ( return . ((),) ) . fn) >>= liftKureM++        let kernel :: Kernel+            kernel = Kernel+                { resumeK = \ name -> sendDone $ \ st -> findWithErrMsg name st (\ msg -> throwGhcException $ ProgramError $ msg ++ ", exiting HERMIT and aborting GHC compilation.") (return.snd)++                , abortK  = sendDone $ \ _ -> throwGhcException (ProgramError "Exiting HERMIT and aborting GHC compilation.")++                , applyK = \ name r hm_env -> sendReq $ \ st -> findWithErrMsg name st fail $ \ (defs, guts) -> runHM hm_env+                                                                                                               defs+                                                                                                               (\ defs' guts' -> do ast <- liftIO $ takeMVar nextASTname+                                                                                                                                    return $ return (ast, insert ast (defs',guts') st))+                                                                                                               (return . fail)+                                                                                                               (apply r (initHermitC guts) guts)++                , queryK = \ name t hm_env -> sendReqRead $ \ st -> findWithErrMsg name st fail $ \ (defs, core) -> runHM hm_env+                                                                                                                      defs+                                                                                                                      (\ _ -> return.return)+                                                                                                                      (return . fail)+                                                                                                                      (apply t (initHermitC core) core)++                , deleteK = \ name -> sendReqWrite (return . delete name)++                , listK = sendReqRead (return . return . keys) >>= liftKureM+                }++        -- We always start with AST 0+        ast0 <- liftIO $ takeMVar nextASTname++        let loop :: KernelState -> CoreM ModGuts+            loop st = do+                m <- liftIO $ takeMVar msgMV+                case m of+                  Req fn rep -> fn st >>= runKureM (\ (a,st') -> liftIO (putMVar rep $ return a) >> loop st')+                                                   (\ msg     -> liftIO (putMVar rep $ fail msg) >> loop st)+                  Done fn -> fn st++        _pid <- liftIO $ forkIO $ callback kernel ast0++        loop (singleton ast0 (empty, modGuts))++        -- (Kill the pid'd thread? do we need to?)++findWithErrMsg :: AST -> Map AST v -> (String -> b) -> (v -> b) -> b+findWithErrMsg ast m f = find ast m (f $ "Cannot find syntax tree: " ++ show ast)++find :: Ord k => k -> Map k v -> b -> (v -> b) -> b+find k m f s = maybe f s (lookup k m)
+ src/HERMIT/Kernel/Scoped.hs view
@@ -0,0 +1,167 @@+{-# LANGUAGE RankNTypes, FlexibleContexts, InstanceSigs #-}+module HERMIT.Kernel.Scoped+    ( Direction(..)+    , LocalPath+    , moveLocally+    , ScopedKernel(..)+    , SAST(..)+    , scopedKernel+    ) where++import Control.Arrow+import Control.Concurrent.STM+import Control.Exception (bracketOnError)+import Control.Monad+import Control.Monad.IO.Class++import Data.Maybe (fromMaybe)+import Data.Monoid (mempty)+import qualified Data.IntMap as I++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure+import HERMIT.GHC hiding (Direction,L)+import HERMIT.Monad+import HERMIT.Kernel++----------------------------------------------------------------------------++-- | A primitive means of denoting navigation of a tree (within a local scope).+data Direction = L -- ^ Left+               | R -- ^ Right+               | U -- ^ Up+               | T -- ^ Top+               deriving (Eq,Show)++pathStack2Paths :: [LocalPath crumb] -> LocalPath crumb -> [Path crumb]+pathStack2Paths ps p = reverse (map snocPathToPath (p:ps))++-- | Movement confined within the local scope.+moveLocally :: Direction -> LocalPathH -> LocalPathH+moveLocally d (SnocPath p) = case p of+                               []     -> mempty+                               cr:crs -> case d of+                                           T -> mempty+                                           U -> SnocPath crs+                                           L -> SnocPath (fromMaybe cr (deprecatedLeftSibling cr)  : crs)+                                           R -> SnocPath (fromMaybe cr (deprecatedRightSibling cr) : crs)+++pathStackToLens :: (Injection ModGuts g, Walker HermitC g) => [LocalPathH] -> LocalPathH -> LensH ModGuts g+pathStackToLens ps p = injectL >>> pathL (concat $ pathStack2Paths ps p)++-- This function is used to check the validity of paths, so which sum type we use is important.+testPathStackT :: [LocalPathH] -> LocalPathH -> TranslateH ModGuts Bool+testPathStackT ps p = testLensT (pathStackToLens ps p :: LensH ModGuts CoreTC)++----------------------------------------------------------------------------++-- | An alternative HERMIT kernel, that provides scoping.+data ScopedKernel = ScopedKernel+    { resumeS      :: (MonadIO m, MonadCatch m) =>                SAST -> m ()+    , abortS       ::  MonadIO m                =>                        m ()+    , applyS       :: (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g)+                   => RewriteH g -> HermitMEnv ->                 SAST -> m SAST+    , queryS       :: (MonadIO m, MonadCatch m, Injection ModGuts g, Walker HermitC g)+                   => TranslateH g a -> HermitMEnv ->             SAST -> m a+    , deleteS      :: (MonadIO m, MonadCatch m) =>                SAST -> m ()+    , listS        ::  MonadIO m                =>                        m [SAST]+    , pathS        :: (MonadIO m, MonadCatch m) =>                SAST -> m [PathH]+    , modPathS     :: (MonadIO m, MonadCatch m)+                   => (LocalPathH -> LocalPathH) -> HermitMEnv -> SAST -> m SAST+    , beginScopeS  :: (MonadIO m, MonadCatch m) =>                SAST -> m SAST+    , endScopeS    :: (MonadIO m, MonadCatch m) =>                SAST -> m SAST+    -- means of accessing the underlying kernel, obviously for unsafe purposes+    , kernelS      ::                                                     Kernel+    , toASTS       :: (MonadIO m, MonadCatch m) =>                SAST -> m AST+    }++-- | A /handle/ for an 'AST' combined with scoping information.+newtype SAST = SAST Int deriving (Eq, Ord, Show)++-- path stack, representing the base path, then the relative path+type SASTStore = I.IntMap (AST, [LocalPathH], LocalPathH)++get :: Monad m => Int -> SASTStore -> m (AST, [LocalPathH], LocalPathH)+get sAst m = maybe (fail "scopedKernel: invalid SAST") return (I.lookup sAst m)++-- | Ensures that the TMVar is replaced when an error is thrown, and all exceptions are lifted into MonadCatch failures.+safeTakeTMVar :: (MonadCatch m, MonadIO m) => TMVar a -> (a -> IO b) -> m b+safeTakeTMVar mvar = liftAndCatchIO . bracketOnError (atomically $ takeTMVar mvar) (atomically . putTMVar mvar)++-- | Start a HERMIT client by providing an IO function that takes the initial 'ScopedKernel' and inital 'SAST' handle.+--   The 'Modguts' to 'CoreM' Modguts' function required by GHC Plugins is returned.+scopedKernel :: (ScopedKernel -> SAST -> IO ()) -> ModGuts -> CoreM ModGuts+scopedKernel callback = hermitKernel $ \ kernel initAST -> do+    store <- newTMVarIO $ I.fromList [(0,(initAST, [], mempty))]+    key <- newTMVarIO (1::Int)++    let newKey = do+            k <- takeTMVar key+            putTMVar key (k+1)+            return k++        skernel = ScopedKernel+            { resumeS     = \ (SAST sAst) -> liftAndCatchIO $ do+                                m <- atomically $ readTMVar store+                                (ast,_,_) <- get sAst m+                                resumeK kernel ast+            , abortS      = liftIO $ abortK kernel+            , applyS      = \ rr env (SAST sAst) -> safeTakeTMVar store $ \ m -> do+                                (ast, base, rel) <- get sAst m+                                applyK kernel ast (focusR (pathStackToLens base rel) rr) env+                                  >>= runKureM (\ ast' -> atomically $ do k <- newKey+                                                                          putTMVar store $ I.insert k (ast', base, rel) m+                                                                          return $ SAST k)+                                               fail+            , queryS      = \ t env (SAST sAst) -> liftAndCatchIO $ do+                                m <- atomically $ readTMVar store+                                (ast, base, rel) <- get sAst m+                                queryK kernel ast (focusT (pathStackToLens base rel) t) env+                                    >>= liftKureM+            , deleteS     = \ (SAST sAst) -> safeTakeTMVar store $ \ m -> do+                                (ast,_,_) <- get sAst m+                                let m' = I.delete sAst m+                                    fst3 (x,_,_) = x+                                    asts = I.foldr ((:) . fst3) [] m'+                                when (ast `notElem` asts) $ deleteK kernel ast+                                atomically $ putTMVar store m'+            , listS       = do m <- liftIO $ atomically $ readTMVar store+                               return [ SAST sAst | sAst <- I.keys m ]+            , pathS       = \ (SAST sAst) -> liftAndCatchIO $ do+                                m <- atomically $ readTMVar store+                                (_, base, rel) <- get sAst m+                                return $ pathStack2Paths base rel+            , modPathS    = \ f env (SAST sAst) -> safeTakeTMVar store $ \ m -> do+                                (ast, base, rel) <- get sAst m+                                let rel' = f rel+                                queryK kernel ast (testPathStackT base rel') env+                                  >>= runKureM (\ b -> if rel == rel'+                                                        then fail "Path is unchanged, nothing to do."+                                                        else if b+                                                              then atomically $ do k <- newKey+                                                                                   putTMVar store $ I.insert k (ast, base, rel') m+                                                                                   return $ SAST k+                                                              else fail "Invalid path created.")+                                               fail+            , beginScopeS = \ (SAST sAst) -> safeTakeTMVar store $ \m -> do+                                (ast, base, rel) <- get sAst m+                                atomically $ do k <- newKey+                                                putTMVar store $ I.insert k (ast, rel : base, mempty) m+                                                return $ SAST k+            , endScopeS   = \ (SAST sAst) -> safeTakeTMVar store $ \m -> do+                                (ast, base, _) <- get sAst m+                                case base of+                                    []          -> fail "Scoped Kernel: no scope to end."+                                    rel : base' -> atomically $ do k <- newKey+                                                                   putTMVar store $ I.insert k (ast, base', rel) m+                                                                   return $ SAST k+            , kernelS     = kernel+            , toASTS      = \ (SAST sAst) -> liftAndCatchIO $ do+                                m <- atomically $ readTMVar store+                                (ast, _, _) <- get sAst m+                                return ast+            }++    callback skernel $ SAST 0
+ src/HERMIT/Kure.hs view
@@ -0,0 +1,1324 @@+{-# LANGUAGE CPP, LambdaCase, FlexibleInstances, MultiParamTypeClasses, FlexibleContexts, UndecidableInstances, ScopedTypeVariables, InstanceSigs #-}++module HERMIT.Kure+       (+       -- * KURE++       -- | All the required functionality of KURE is exported here, so other modules do not need to import KURE directly.+         module Language.KURE+       , module Language.KURE.BiTranslate+       , module Language.KURE.Lens+       , module Language.KURE.ExtendableContext+       , module Language.KURE.Pathfinder+       -- * Sub-Modules+       , module HERMIT.Kure.SumTypes+       -- * Synonyms+       , TranslateH+       , RewriteH+       , BiRewriteH+       , LensH+       , PathH++       -- * Congruence combinators+       -- ** Modguts+       , modGutsT, modGutsR+       -- ** Program+       , progNilT+       , progConsT, progConsAllR, progConsAnyR, progConsOneR+       -- ** Binding Groups+       , nonRecT, nonRecAllR, nonRecAnyR, nonRecOneR+       , recT, recAllR, recAnyR, recOneR+       -- ** Recursive Definitions+       , defT, defAllR, defAnyR, defOneR+       -- ** Case Alternatives+       , altT, altAllR, altAnyR, altOneR+       -- ** Expressions+       , varT, varR+       , litT, litR+       , appT, appAllR, appAnyR, appOneR+       , lamT, lamAllR, lamAnyR, lamOneR+       , letT, letAllR, letAnyR, letOneR+       , caseT, caseAllR, caseAnyR, caseOneR+       , castT, castAllR, castAnyR, castOneR+       , tickT, tickAllR, tickAnyR, tickOneR+       , typeT, typeR+       , coercionT, coercionR+       -- ** Composite Congruence Combinators+       , defOrNonRecT, defOrNonRecAllR, defOrNonRecAnyR, defOrNonRecOneR+       , recDefT, recDefAllR, recDefAnyR, recDefOneR+       , letNonRecT, letNonRecAllR, letNonRecAnyR, letNonRecOneR+       , letRecT, letRecAllR, letRecAnyR, letRecOneR+       , letRecDefT, letRecDefAllR, letRecDefAnyR, letRecDefOneR+       , consNonRecT, consNonRecAllR, consNonRecAnyR, consNonRecOneR+       , consRecT, consRecAllR, consRecAnyR, consRecOneR+       , consRecDefT, consRecDefAllR, consRecDefAnyR, consRecDefOneR+       , caseAltT, caseAltAllR, caseAltAnyR, caseAltOneR+       -- ** Types+       , tyVarT, tyVarR+       , litTyT, litTyR+       , appTyT, appTyAllR, appTyAnyR, appTyOneR+       , funTyT, funTyAllR, funTyAnyR, funTyOneR+       , forAllTyT, forAllTyAllR, forAllTyAnyR, forAllTyOneR+       , tyConAppT, tyConAppAllR, tyConAppAnyR, tyConAppOneR+       -- ** Coercions+       , reflT, reflR+       , tyConAppCoT, tyConAppCoAllR, tyConAppCoAnyR, tyConAppCoOneR+       , appCoT, appCoAllR, appCoAnyR, appCoOneR+       , forAllCoT, forAllCoAllR, forAllCoAnyR, forAllCoOneR+       , coVarCoT, coVarCoR+       , axiomInstCoT, axiomInstCoAllR, axiomInstCoAnyR, axiomInstCoOneR+#if __GLASGOW_HASKELL__ > 706+#else+       , unsafeCoT, unsafeCoAllR, unsafeCoAnyR, unsafeCoOneR+#endif+       , symCoT, symCoR+       , transCoT, transCoAllR, transCoAnyR, transCoOneR+       , nthCoT, nthCoAllR, nthCoAnyR, nthCoOneR+       , instCoT, instCoAllR, instCoAnyR, instCoOneR+#if __GLASGOW_HASKELL__ > 706+       , lrCoT, lrCoAllR, lrCoAnyR, lrCoOneR+#else+#endif+       -- * Conversion to deprecated Int representation+       , deprecatedIntToCrumbT+       , deprecatedIntToPathT+       )+where++import Language.KURE+import Language.KURE.BiTranslate+import Language.KURE.Lens+import Language.KURE.ExtendableContext+import Language.KURE.Pathfinder++import HERMIT.Context+import HERMIT.Core+import HERMIT.GHC+import HERMIT.Monad+import HERMIT.Kure.SumTypes++import Control.Monad++import Data.Monoid (mempty)++---------------------------------------------------------------------++type TranslateH a b = Translate HermitC HermitM a b+type RewriteH a     = Rewrite   HermitC HermitM a+type BiRewriteH a   = BiRewrite HermitC HermitM a+type LensH a b      = Lens      HermitC HermitM a b+type PathH          = Path Crumb++-- I find it annoying that Applicative is not a superclass of Monad.+(<$>) :: Monad m => (a -> b) -> m a -> m b+(<$>) = liftM+{-# INLINE (<$>) #-}++(<*>) :: Monad m => m (a -> b) -> m a -> m b+(<*>) = ap+{-# INLINE (<*>) #-}++---------------------------------------------------------------------++-- | Walking over modules, programs, binding groups, definitions, expressions and case alternatives.+instance (ExtendPath c Crumb, AddBindings c) => Walker c Core where++  allR :: forall m. MonadCatch m => Rewrite c m Core -> Rewrite c m Core+  allR r = prefixFailMsg "allR failed: " $+           rewrite $ \ c -> \case+             GutsCore guts  -> inject <$> apply allRmodguts c guts+             ProgCore p     -> inject <$> apply allRprog c p+             BindCore bn    -> inject <$> apply allRbind c bn+             DefCore def    -> inject <$> apply allRdef c def+             AltCore alt    -> inject <$> apply allRalt c alt+             ExprCore e     -> inject <$> apply allRexpr c e+    where+      allRmodguts :: MonadCatch m => Rewrite c m ModGuts+      allRmodguts = modGutsR (extractR r)+      {-# INLINE allRmodguts #-}++      allRprog :: MonadCatch m => Rewrite c m CoreProg+      allRprog = readerT $ \case+                              ProgCons{}  -> progConsAllR (extractR r) (extractR r)+                              _           -> idR+      {-# INLINE allRprog #-}++      allRbind :: MonadCatch m => Rewrite c m CoreBind+      allRbind = readerT $ \case+                              NonRec{}  -> nonRecAllR idR (extractR r) -- we don't descend into the Var+                              Rec _     -> recAllR (const $ extractR r)+      {-# INLINE allRbind #-}++      allRdef :: MonadCatch m => Rewrite c m CoreDef+      allRdef = defAllR idR (extractR r) -- we don't descend into the Id+      {-# INLINE allRdef #-}++      allRalt :: MonadCatch m => Rewrite c m CoreAlt+      allRalt = altAllR idR (const idR) (extractR r) -- we don't descend into the AltCon or Vars+      {-# INLINE allRalt #-}++      allRexpr :: MonadCatch m => Rewrite c m CoreExpr+      allRexpr = readerT $ \case+                              App{}   -> appAllR (extractR r) (extractR r)+                              Lam{}   -> lamAllR idR (extractR r) -- we don't descend into the Var+                              Let{}   -> letAllR (extractR r) (extractR r)+                              Case{}  -> caseAllR (extractR r) idR idR (const $ extractR r) -- we don't descend into the case binder or Type+                              Cast{}  -> castAllR (extractR r) idR -- we don't descend into the Coercion+                              Tick{}  -> tickAllR idR (extractR r) -- we don't descend into the Tickish+                              _       -> idR+      {-# INLINE allRexpr #-}++-- NOTE: I tried telling GHC to inline allR and compilation hit the (default) simplifier tick limit.+-- TODO: Investigate whether that was achieving useful optimisations.++---------------------------------------------------------------------++-- | Walking over types (only).+instance (ExtendPath c Crumb, AddBindings c) => Walker c Type where++  allR :: MonadCatch m => Rewrite c m Type -> Rewrite c m Type+  allR r = prefixFailMsg "allR failed: " $+           readerT $ \case+                        AppTy{}     -> appTyAllR r r+                        FunTy{}     -> funTyAllR r r+                        ForAllTy{}  -> forAllTyAllR idR r+                        TyConApp{}  -> tyConAppAllR idR (const r)+                        _           -> idR++---------------------------------------------------------------------++-- | Walking over coercions (only).+instance (ExtendPath c Crumb, AddBindings c) => Walker c Coercion where++  allR :: MonadCatch m => Rewrite c m Coercion -> Rewrite c m Coercion+  allR r = prefixFailMsg "allR failed: " $+           readerT $ \case+                        TyConAppCo{}  -> tyConAppCoAllR idR (const r)+                        AppCo{}       -> appCoAllR r r+                        ForAllCo{}    -> forAllCoAllR idR r+                        SymCo{}       -> symCoR r+                        TransCo{}     -> transCoAllR r r+                        NthCo{}       -> nthCoAllR idR r+                        InstCo{}      -> instCoAllR r idR+#if __GLASGOW_HASKELL__ > 706+                        LRCo{}        -> lrCoAllR idR r+                        AxiomInstCo{} -> axiomInstCoAllR idR idR (const r)+#else+                        AxiomInstCo{} -> axiomInstCoAllR idR (const r)+#endif+                        _             -> idR++---------------------------------------------------------------------++-- | Walking over types and coercions.+instance (ExtendPath c Crumb, AddBindings c) => Walker c TyCo where++  allR :: forall m. MonadCatch m => Rewrite c m TyCo -> Rewrite c m TyCo+  allR r = prefixFailMsg "allR failed: " $+           rewrite $ \ c -> \case+             TypeCore ty     -> inject <$> apply (allR $ extractR r) c ty -- exploiting the fact that types do not contain coercions+             CoercionCore co -> inject <$> apply allRcoercion c co+    where+      allRcoercion :: MonadCatch m => Rewrite c m Coercion+      allRcoercion = readerT $ \case+                              Refl{}        -> reflR (extractR r)+                              TyConAppCo{}  -> tyConAppCoAllR idR (const $ extractR r) -- we don't descend into the TyCon+                              AppCo{}       -> appCoAllR (extractR r) (extractR r)+                              ForAllCo{}    -> forAllCoAllR idR (extractR r) -- we don't descend into the TyVar+#if __GLASGOW_HASKELL__ > 706+#else+                              UnsafeCo{}    -> unsafeCoAllR (extractR r) (extractR r)+#endif+                              SymCo{}       -> symCoR (extractR r)+                              TransCo{}     -> transCoAllR (extractR r) (extractR r)+                              InstCo{}      -> instCoAllR (extractR r) (extractR r)+                              NthCo{}       -> nthCoAllR idR (extractR r) -- we don't descend into the Int+#if __GLASGOW_HASKELL__ > 706+                              LRCo{}        -> lrCoAllR idR (extractR r)+                              AxiomInstCo{} -> axiomInstCoAllR idR idR (const $ extractR r) -- we don't descend into the axiom or index+#else+                              AxiomInstCo{} -> axiomInstCoAllR idR (const $ extractR r) -- we don't descend into the axiom+#endif+                              _             -> idR+      {-# INLINE allRcoercion #-}++---------------------------------------------------------------------++-- | Walking over modules, programs, binding groups, definitions, expressions and case alternatives.+instance (ExtendPath c Crumb, AddBindings c) => Walker c CoreTC where++  allR :: forall m. MonadCatch m => Rewrite c m CoreTC -> Rewrite c m CoreTC+  allR r = prefixFailMsg "allR failed: " $+           rewrite $ \ c -> \case+             Core (GutsCore guts)  -> inject <$> apply allRmodguts c guts+             Core (ProgCore p)     -> inject <$> apply allRprog c p+             Core (BindCore bn)    -> inject <$> apply allRbind c bn+             Core (DefCore def)    -> inject <$> apply allRdef c def+             Core (AltCore alt)    -> inject <$> apply allRalt c alt+             Core (ExprCore e)     -> inject <$> apply allRexpr c e+             TyCo tyCo             -> inject <$> apply (allR $ extractR r) c tyCo -- exploiting the fact that only types and coercions appear within types and coercions+    where+      allRmodguts :: MonadCatch m => Rewrite c m ModGuts+      allRmodguts = modGutsR (extractR r)+      {-# INLINE allRmodguts #-}++      allRprog :: MonadCatch m => Rewrite c m CoreProg+      allRprog = readerT $ \case+                              ProgCons{}  -> progConsAllR (extractR r) (extractR r)+                              _           -> idR+      {-# INLINE allRprog #-}++      allRbind :: MonadCatch m => Rewrite c m CoreBind+      allRbind = readerT $ \case+                              NonRec{}  -> nonRecAllR idR (extractR r) -- we don't descend into the Var+                              Rec _     -> recAllR (const $ extractR r)+      {-# INLINE allRbind #-}++      allRdef :: MonadCatch m => Rewrite c m CoreDef+      allRdef = defAllR idR (extractR r) -- we don't descend into the Id+      {-# INLINE allRdef #-}++      allRalt :: MonadCatch m => Rewrite c m CoreAlt+      allRalt = altAllR idR (const idR) (extractR r) -- we don't descend into the AltCon or Vars+      {-# INLINE allRalt #-}++      allRexpr :: MonadCatch m => Rewrite c m CoreExpr+      allRexpr = readerT $ \case+                              App{}      -> appAllR (extractR r) (extractR r)+                              Lam{}      -> lamAllR idR (extractR r) -- we don't descend into the Var+                              Let{}      -> letAllR (extractR r) (extractR r)+                              Case{}     -> caseAllR (extractR r) idR (extractR r) (const $ extractR r) -- we don't descend into the case binder+                              Cast{}     -> castAllR (extractR r) (extractR r)+                              Tick{}     -> tickAllR idR (extractR r) -- we don't descend into the Tickish+                              Type{}     -> typeR (extractR r)+                              Coercion{} -> coercionR (extractR r)+                              _          -> idR+      {-# INLINE allRexpr #-}++---------------------------------------------------------------------++-- | Translate a module.+--   Slightly different to the other congruence combinators: it passes in /all/ of the original to the reconstruction function.+modGutsT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreProg a -> (ModGuts -> a -> b) -> Translate c m ModGuts b+modGutsT t f = translate $ \ c guts -> f guts <$> apply t (c @@ ModGuts_Prog) (bindsToProg $ mg_binds guts)+{-# INLINE modGutsT #-}++-- | Rewrite the 'CoreProg' child of a module.+modGutsR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreProg -> Rewrite c m ModGuts+modGutsR r = modGutsT r (\ guts p -> guts {mg_binds = progToBinds p})+{-# INLINE modGutsR #-}++---------------------------------------------------------------------++-- | Translate an empty list.+progNilT :: Monad m => b -> Translate c m CoreProg b+progNilT b = contextfreeT $ \case+                               ProgNil       -> return b+                               ProgCons _ _  -> fail "not an empty program."+{-# INLINE progNilT #-}++-- | Translate a program of the form: ('CoreBind' @:@ 'CoreProg')+progConsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreProg a2 -> (a1 -> a2 -> b) -> Translate c m CoreProg b+progConsT t1 t2 f = translate $ \ c -> \case+                                          ProgCons bd p -> f <$> apply t1 (c @@ ProgCons_Head) bd <*> apply t2 (addBindingGroup bd c @@ ProgCons_Tail) p+                                          _             -> fail "not a non-empty program."+{-# INLINE progConsT #-}++-- | Rewrite all children of a program of the form: ('CoreBind' @:@ 'CoreProg')+progConsAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg+progConsAllR r1 r2 = progConsT r1 r2 ProgCons+{-# INLINE progConsAllR #-}++-- | Rewrite any children of a program of the form: ('CoreBind' @:@ 'CoreProg')+progConsAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg+progConsAnyR r1 r2 = unwrapAnyR $ progConsAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE progConsAnyR #-}++-- | Rewrite one child of a program of the form: ('CoreBind' @:@ 'CoreProg')+progConsOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg+progConsOneR r1 r2 = unwrapOneR $  progConsAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE progConsOneR #-}++---------------------------------------------------------------------++-- | Translate a binding group of the form: @NonRec@ 'Var' 'CoreExpr'+nonRecT :: (ExtendPath c Crumb, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreBind b+nonRecT t1 t2 f = translate $ \ c -> \case+                                        NonRec v e -> f <$> apply t1 (c @@ NonRec_Var) v <*> apply t2 (c @@ NonRec_RHS) e+                                        _          -> fail "not a non-recursive binding group."+{-# INLINE nonRecT #-}++-- | Rewrite all children of a binding group of the form: @NonRec@ 'Var' 'CoreExpr'+nonRecAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind+nonRecAllR r1 r2 = nonRecT r1 r2 NonRec+{-# INLINE nonRecAllR #-}++-- | Rewrite any children of a binding group of the form: @NonRec@ 'Var' 'CoreExpr'+nonRecAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind+nonRecAnyR r1 r2 = unwrapAnyR (nonRecAllR (wrapAnyR r1) (wrapAnyR r2))+{-# INLINE nonRecAnyR #-}++-- | Rewrite one child of a binding group of the form: @NonRec@ 'Var' 'CoreExpr'+nonRecOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind+nonRecOneR r1 r2 = unwrapOneR (nonRecAllR (wrapOneR r1) (wrapOneR r2))+{-# INLINE nonRecOneR #-}+++-- | Translate a binding group of the form: @Rec@ ['CoreDef']+recT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a) -> ([a] -> b) -> Translate c m CoreBind b+recT t f = translate $ \ c -> \case+         Rec bds -> -- The group is recursive, so we add all other bindings in the group to the context (excluding the one under consideration).+                    f <$> sequence [ apply (t n) (addDefBindingsExcept n bds c @@ Rec_Def n) (Def i e) -- here we convert from (Id,CoreExpr) to CoreDef+                                   | ((i,e),n) <- zip bds [0..]+                                   ]+         _       -> fail "not a recursive binding group."+{-# INLINE recT #-}++-- | Rewrite all children of a binding group of the form: @Rec@ ['CoreDef']+recAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind+recAllR rs = recT rs defsToRecBind+{-# INLINE recAllR #-}++-- | Rewrite any children of a binding group of the form: @Rec@ ['CoreDef']+recAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind+recAnyR rs = unwrapAnyR $ recAllR (wrapAnyR . rs)+{-# INLINE recAnyR #-}++-- | Rewrite one child of a binding group of the form: @Rec@ ['CoreDef']+recOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind+recOneR rs = unwrapOneR $ recAllR (wrapOneR . rs)+{-# INLINE recOneR #-}++---------------------------------------------------------------------++-- | Translate a recursive definition of the form: @Def@ 'Id' 'CoreExpr'+defT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Id a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreDef b+defT t1 t2 f = translate $ \ c (Def i e) -> f <$> apply t1 (c @@ Def_Id) i <*> apply t2 (addDefBinding i c @@ Def_RHS) e+{-# INLINE defT #-}++-- | Rewrite all children of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'+defAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef+defAllR r1 r2 = defT r1 r2 Def+{-# INLINE defAllR #-}++-- | Rewrite any children of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'+defAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef+defAnyR r1 r2 = unwrapAnyR (defAllR (wrapAnyR r1) (wrapAnyR r2))+{-# INLINE defAnyR #-}++-- | Rewrite one child of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'+defOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef+defOneR r1 r2 = unwrapOneR (defAllR (wrapOneR r1) (wrapOneR r2))+{-# INLINE defOneR #-}++---------------------------------------------------------------------++-- | Translate a case alternative of the form: ('AltCon', ['Var'], 'CoreExpr')+altT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m AltCon a1 -> (Int -> Translate c m Var a2) -> Translate c m CoreExpr a3 -> (a1 -> [a2] -> a3 -> b) -> Translate c m CoreAlt b+altT t1 ts t2 f = translate $ \ c (con,vs,e) -> f <$> apply t1 (c @@ Alt_Con) con+                                                  <*> sequence [ apply (ts n) (c @@ Alt_Var n) v | (v,n) <- zip vs [1..] ]+                                                  <*> apply t2 (addAltBindings vs c @@ Alt_RHS) e+{-# INLINE altT #-}++-- | Rewrite all children of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')+altAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt+altAllR r1 rs r2 = altT r1 rs r2 (,,)+{-# INLINE altAllR #-}++-- | Rewrite any children of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')+altAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt+altAnyR r1 rs r2 = unwrapAnyR (altAllR (wrapAnyR r1) (wrapAnyR . rs) (wrapAnyR r2))+{-# INLINE altAnyR #-}++-- | Rewrite one child of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')+altOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt+altOneR r1 rs r2 = unwrapOneR (altAllR (wrapOneR r1) (wrapOneR . rs) (wrapOneR r2))+{-# INLINE altOneR #-}++---------------------------------------------------------------------++-- | Translate an expression of the form: @Var@ 'Id'+varT :: (ExtendPath c Crumb, Monad m) => Translate c m Id b -> Translate c m CoreExpr b+varT t = translate $ \ c -> \case+                               Var v -> apply t (c @@ Var_Id) v+                               _     -> fail "not a variable."+{-# INLINE varT #-}++-- | Rewrite the 'Id' child in an expression of the form: @Var@ 'Id'+varR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr+varR r = varT (Var <$> r)+{-# INLINE varR #-}+++-- | Translate an expression of the form: @Lit@ 'Literal'+litT :: (ExtendPath c Crumb, Monad m) => Translate c m Literal b -> Translate c m CoreExpr b+litT t = translate $ \ c -> \case+                               Lit x -> apply t (c @@ Lit_Lit) x+                               _     -> fail "not a literal."+{-# INLINE litT #-}++-- | Rewrite the 'Literal' child in an expression of the form: @Lit@ 'Literal'+litR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Literal -> Rewrite c m CoreExpr+litR r = litT (Lit <$> r)+{-# INLINE litR #-}+++-- | Translate an expression of the form: @App@ 'CoreExpr' 'CoreExpr'+appT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b+appT t1 t2 f = translate $ \ c -> \case+                                     App e1 e2 -> f <$> apply t1 (c @@ App_Fun) e1 <*> apply t2 (c @@ App_Arg) e2+                                     _         -> fail "not an application."+{-# INLINE appT #-}++-- | Rewrite all children of an expression of the form: @App@ 'CoreExpr' 'CoreExpr'+appAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+appAllR r1 r2 = appT r1 r2 App+{-# INLINE appAllR #-}++-- | Rewrite any children of an expression of the form: @App@ 'CoreExpr' 'CoreExpr'+appAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+appAnyR r1 r2 = unwrapAnyR $ appAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE appAnyR #-}++-- | Rewrite one child of an expression of the form: @App@ 'CoreExpr' 'CoreExpr'+appOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+appOneR r1 r2 = unwrapOneR $ appAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE appOneR #-}+++-- | Translate an expression of the form: @Lam@ 'Var' 'CoreExpr'+lamT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b+lamT t1 t2 f = translate $ \ c -> \case+                                     Lam v e -> f <$> apply t1 (c @@ Lam_Var) v <*> apply t2 (addLambdaBinding v c @@ Lam_Body) e+                                     _       -> fail "not a lambda."+{-# INLINE lamT #-}++-- | Rewrite all children of an expression of the form: @Lam@ 'Var' 'CoreExpr'+lamAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+lamAllR r1 r2 = lamT r1 r2 Lam+{-# INLINE lamAllR #-}++-- | Rewrite any children of an expression of the form: @Lam@ 'Var' 'CoreExpr'+lamAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+lamAnyR r1 r2 = unwrapAnyR $ lamAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE lamAnyR #-}++-- | Rewrite one child of an expression of the form: @Lam@ 'Var' 'CoreExpr'+lamOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+lamOneR r1 r2 = unwrapOneR $ lamAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE lamOneR #-}+++-- | Translate an expression of the form: @Let@ 'CoreBind' 'CoreExpr'+letT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b+letT t1 t2 f = translate $ \ c -> \case+        Let bds e -> -- Note we use the *original* context for the binding group.+                     -- If the bindings are recursive, they will be added to the context by recT.+                     f <$> apply t1 (c @@ Let_Bind) bds <*> apply t2 (addBindingGroup bds c @@ Let_Body) e+        _         -> fail "not a let node."+{-# INLINE letT #-}++-- | Rewrite all children of an expression of the form: @Let@ 'CoreBind' 'CoreExpr'+letAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letAllR r1 r2 = letT r1 r2 Let+{-# INLINE letAllR #-}++-- | Rewrite any children of an expression of the form: @Let@ 'CoreBind' 'CoreExpr'+letAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letAnyR r1 r2 = unwrapAnyR $ letAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE letAnyR #-}++-- | Rewrite one child of an expression of the form: @Let@ 'CoreBind' 'CoreExpr'+letOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letOneR r1 r2 = unwrapOneR $ letAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE letOneR #-}+++-- | Translate an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']+caseT :: (ExtendPath c Crumb, AddBindings c, Monad m)+      => Translate c m CoreExpr e+      -> Translate c m Id w+      -> Translate c m Type ty+      -> (Int -> Translate c m CoreAlt alt)+      -> (e -> w -> ty -> [alt] -> b)+      -> Translate c m CoreExpr b+caseT te tw tty talts f = translate $ \ c -> \case+         Case e w ty alts -> f <$> apply te (c @@ Case_Scrutinee) e+                               <*> apply tw (c @@ Case_Binder) w+                               <*> apply tty (c @@ Case_Type) ty+                               <*> sequence [ apply (talts n) (addCaseWildBinding (w,e,alt) c @@ Case_Alt n) alt+                                            | (alt,n) <- zip alts [0..]+                                            ]+         _                -> fail "not a case."+{-# INLINE caseT #-}++-- | Rewrite all children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']+caseAllR :: (ExtendPath c Crumb, AddBindings c, Monad m)+         => Rewrite c m CoreExpr+         -> Rewrite c m Id+         -> Rewrite c m Type+         -> (Int -> Rewrite c m CoreAlt)+         -> Rewrite c m CoreExpr+caseAllR re rw rty ralts = caseT re rw rty ralts Case+{-# INLINE caseAllR #-}++-- | Rewrite any children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']+caseAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)+         => Rewrite c m CoreExpr+         -> Rewrite c m Id+         -> Rewrite c m Type+         -> (Int -> Rewrite c m CoreAlt)+         -> Rewrite c m CoreExpr+caseAnyR re rw rty ralts = unwrapAnyR $ caseAllR (wrapAnyR re) (wrapAnyR rw) (wrapAnyR rty) (wrapAnyR . ralts)+{-# INLINE caseAnyR #-}++-- | Rewrite one child of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']+caseOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)+         => Rewrite c m CoreExpr+         -> Rewrite c m Id+         -> Rewrite c m Type+         -> (Int -> Rewrite c m CoreAlt)+         -> Rewrite c m CoreExpr+caseOneR re rw rty ralts = unwrapOneR $ caseAllR (wrapOneR re) (wrapOneR rw) (wrapOneR rty) (wrapOneR . ralts)+{-# INLINE caseOneR #-}+++-- | Translate an expression of the form: @Cast@ 'CoreExpr' 'Coercion'+castT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b+castT t1 t2 f = translate $ \ c -> \case+                                      Cast e co -> f <$> apply t1 (c @@ Cast_Expr) e <*> apply t2 (c @@ Cast_Co) co+                                      _         -> fail "not a cast."+{-# INLINE castT #-}++-- | Rewrite all children of an expression of the form: @Cast@ 'CoreExpr' 'Coercion'+castAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr+castAllR r1 r2 = castT r1 r2 Cast+{-# INLINE castAllR #-}++-- | Rewrite any children of an expression of the form: @Cast@ 'CoreExpr' 'Coercion'+castAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr+castAnyR r1 r2 = unwrapAnyR $ castAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE castAnyR #-}++-- | Rewrite one child of an expression of the form: @Cast@ 'CoreExpr' 'Coercion'+castOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr+castOneR r1 r2 = unwrapOneR $ castAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE castOneR #-}+++-- | Translate an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'+tickT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreTickish a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b+tickT t1 t2 f = translate $ \ c -> \case+                                      Tick tk e -> f <$> apply t1 (c @@ Tick_Tick) tk <*> apply t2 (c @@ Tick_Expr) e+                                      _         -> fail "not a tick."+{-# INLINE tickT #-}++-- | Rewrite all children of an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'+tickAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+tickAllR r1 r2 = tickT r1 r2 Tick+{-# INLINE tickAllR #-}++-- | Rewrite any children of an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'+tickAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+tickAnyR r1 r2 = unwrapAnyR $ tickAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE tickAnyR #-}++-- | Rewrite any children of an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'+tickOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+tickOneR r1 r2 = unwrapOneR $ tickAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE tickOneR #-}+++-- | Translate an expression of the form: @Type@ 'Type'+typeT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m CoreExpr b+typeT t = translate $ \ c -> \case+                                Type ty -> apply t (c @@ Type_Type) ty+                                _       -> fail "not a type."+{-# INLINE typeT #-}++-- | Rewrite the 'Type' child in an expression of the form: @Type@ 'Type'+typeR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m CoreExpr+typeR r = typeT (Type <$> r)+{-# INLINE typeR #-}+++-- | Translate an expression of the form: @Coercion@ 'Coercion'+coercionT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m CoreExpr b+coercionT t = translate $ \ c -> \case+                                    Coercion co -> apply t (c @@ Co_Co) co+                                    _           -> fail "not a coercion."+{-# INLINE coercionT #-}++-- | Rewrite the 'Coercion' child in an expression of the form: @Coercion@ 'Coercion'+coercionR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m CoreExpr+coercionR r = coercionT (Coercion <$> r)+{-# INLINE coercionR #-}++---------------------------------------------------------------------++-- Some composite congruence combinators to export.++-- | Translate a definition of the form @NonRec 'Var' 'CoreExpr'@ or @Def 'Id' 'CoreExpr'@+defOrNonRecT :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m g b+defOrNonRecT t1 t2 f = promoteBindT (nonRecT t1 t2 f)+                    <+ promoteDefT  (defT    t1 t2 f)+{-# INLINE defOrNonRecT #-}++-- | Rewrite all children of a definition of the form @NonRec 'Var' 'CoreExpr'@ or @Def 'Id' 'CoreExpr'@+defOrNonRecAllR :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m g+defOrNonRecAllR r1 r2 = promoteBindR (nonRecAllR r1 r2)+                     <+ promoteDefR  (defAllR    r1 r2)+{-# INLINE defOrNonRecAllR #-}++-- | Rewrite any children of a definition of the form @NonRec 'Var' 'CoreExpr'@ or @Def 'Id' 'CoreExpr'@+defOrNonRecAnyR :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m g+defOrNonRecAnyR r1 r2 = unwrapAnyR $ defOrNonRecAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE defOrNonRecAnyR #-}++-- | Rewrite one child of a definition of the form @NonRec 'Var' 'CoreExpr'@ or @Def 'Id' 'CoreExpr'@+defOrNonRecOneR :: (Injection CoreBind g, Injection CoreDef g, ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m g+defOrNonRecOneR r1 r2 = unwrapAnyR $ defOrNonRecOneR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE defOrNonRecOneR #-}+++-- | Translate a binding group of the form: @Rec@ [('Id', 'CoreExpr')]+recDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> ([(a1,a2)] -> b) -> Translate c m CoreBind b+recDefT ts = recT (\ n -> uncurry defT (ts n) (,))+{-# INLINE recDefT #-}++-- | Rewrite all children of a binding group of the form: @Rec@ [('Id', 'CoreExpr')]+recDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind+recDefAllR rs = recAllR (\ n -> uncurry defAllR (rs n))+{-# INLINE recDefAllR #-}++-- | Rewrite any children of a binding group of the form: @Rec@ [('Id', 'CoreExpr')]+recDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind+recDefAnyR rs = recAnyR (\ n -> uncurry defAnyR (rs n))+{-# INLINE recDefAnyR #-}++-- | Rewrite one child of a binding group of the form: @Rec@ [('Id', 'CoreExpr')]+recDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind+recDefOneR rs = recOneR (\ n -> uncurry defOneR (rs n))+{-# INLINE recDefOneR #-}+++-- | Translate a program of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'+consNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreProg a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreProg b+consNonRecT t1 t2 t3 f = progConsT (nonRecT t1 t2 (,)) t3 (uncurry f)+{-# INLINE consNonRecT #-}++-- | Rewrite all children of an expression of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'+consNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consNonRecAllR r1 r2 r3 = progConsAllR (nonRecAllR r1 r2) r3+{-# INLINE consNonRecAllR #-}++-- | Rewrite any children of an expression of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'+consNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consNonRecAnyR r1 r2 r3 = progConsAllR (nonRecAnyR r1 r2) r3+{-# INLINE consNonRecAnyR #-}++-- | Rewrite one child of an expression of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'+consNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consNonRecOneR r1 r2 r3 = progConsAllR (nonRecOneR r1 r2) r3+{-# INLINE consNonRecOneR #-}+++-- | Translate an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'+consRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreProg a2 -> ([a1] -> a2 -> b) -> Translate c m CoreProg b+consRecT ts t = progConsT (recT ts id) t+{-# INLINE consRecT #-}++-- | Rewrite all children of an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'+consRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consRecAllR rs r = progConsAllR (recAllR rs) r+{-# INLINE consRecAllR #-}++-- | Rewrite any children of an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'+consRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consRecAnyR rs r = progConsAnyR (recAnyR rs) r+{-# INLINE consRecAnyR #-}++-- | Rewrite one child of an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'+consRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consRecOneR rs r = progConsOneR (recOneR rs) r+{-# INLINE consRecOneR #-}+++-- | Translate an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'+consRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreProg a3 -> ([(a1,a2)] -> a3 -> b) -> Translate c m CoreProg b+consRecDefT ts t = consRecT (\ n -> uncurry defT (ts n) (,)) t+{-# INLINE consRecDefT #-}++-- | Rewrite all children of an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'+consRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consRecDefAllR rs r = consRecAllR (\ n -> uncurry defAllR (rs n)) r+{-# INLINE consRecDefAllR #-}++-- | Rewrite any children of an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'+consRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consRecDefAnyR rs r = consRecAnyR (\ n -> uncurry defAnyR (rs n)) r+{-# INLINE consRecDefAnyR #-}++-- | Rewrite one child of an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'+consRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg+consRecDefOneR rs r = consRecOneR (\ n -> uncurry defOneR (rs n)) r+{-# INLINE consRecDefOneR #-}+++-- | Translate an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'+letNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreExpr a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreExpr b+letNonRecT t1 t2 t3 f = letT (nonRecT t1 t2 (,)) t3 (uncurry f)+{-# INLINE letNonRecT #-}++-- | Rewrite all children of an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'+letNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letNonRecAllR r1 r2 r3 = letAllR (nonRecAllR r1 r2) r3+{-# INLINE letNonRecAllR #-}++-- | Rewrite any children of an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'+letNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letNonRecAnyR r1 r2 r3 = letAnyR (nonRecAnyR r1 r2) r3+{-# INLINE letNonRecAnyR #-}++-- | Rewrite one child of an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'+letNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letNonRecOneR r1 r2 r3 = letOneR (nonRecOneR r1 r2) r3+{-# INLINE letNonRecOneR #-}+++-- | Translate an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'+letRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreExpr a2 -> ([a1] -> a2 -> b) -> Translate c m CoreExpr b+letRecT ts t = letT (recT ts id) t+{-# INLINE letRecT #-}++-- | Rewrite all children of an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'+letRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letRecAllR rs r = letAllR (recAllR rs) r+{-# INLINE letRecAllR #-}++-- | Rewrite any children of an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'+letRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letRecAnyR rs r = letAnyR (recAnyR rs) r+{-# INLINE letRecAnyR #-}++-- | Rewrite one child of an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'+letRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letRecOneR rs r = letOneR (recOneR rs) r+{-# INLINE letRecOneR #-}+++-- | Translate an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'+letRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreExpr a3 -> ([(a1,a2)] -> a3 -> b) -> Translate c m CoreExpr b+letRecDefT ts t = letRecT (\ n -> uncurry defT (ts n) (,)) t+{-# INLINE letRecDefT #-}++-- | Rewrite all children of an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'+letRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letRecDefAllR rs r = letRecAllR (\ n -> uncurry defAllR (rs n)) r+{-# INLINE letRecDefAllR #-}++-- | Rewrite any children of an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'+letRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letRecDefAnyR rs r = letRecAnyR (\ n -> uncurry defAnyR (rs n)) r+{-# INLINE letRecDefAnyR #-}++-- | Rewrite one child of an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'+letRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr+letRecDefOneR rs r = letRecOneR (\ n -> uncurry defOneR (rs n)) r+{-# INLINE letRecDefOneR #-}+++-- | Translate an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]+caseAltT :: (ExtendPath c Crumb, AddBindings c, Monad m)+         => Translate c m CoreExpr sc+         -> Translate c m Id w+         -> Translate c m Type ty+         -> (Int -> (Translate c m AltCon con, (Int -> Translate c m Var v), Translate c m CoreExpr rhs)) -> (sc -> w -> ty -> [(con,[v],rhs)] -> b)+         -> Translate c m CoreExpr b+caseAltT tsc tw tty talts = caseT tsc tw tty (\ n -> let (tcon,tvs,te) = talts n in altT tcon tvs te (,,))+{-# INLINE caseAltT #-}++-- | Rewrite all children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]+caseAltAllR :: (ExtendPath c Crumb, AddBindings c, Monad m)+            => Rewrite c m CoreExpr+            -> Rewrite c m Id+            -> Rewrite c m Type+            -> (Int -> (Rewrite c m AltCon, (Int -> Rewrite c m Var), Rewrite c m CoreExpr))+            -> Rewrite c m CoreExpr+caseAltAllR rsc rw rty ralts = caseAllR rsc rw rty (\ n -> let (rcon,rvs,re) = ralts n in altAllR rcon rvs re)+{-# INLINE caseAltAllR #-}++-- | Rewrite any children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]+caseAltAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)+            => Rewrite c m CoreExpr+            -> Rewrite c m Id+            -> Rewrite c m Type+            -> (Int -> (Rewrite c m AltCon, (Int -> Rewrite c m Var), Rewrite c m CoreExpr))+            -> Rewrite c m CoreExpr+caseAltAnyR rsc rw rty ralts = caseAnyR rsc rw rty (\ n -> let (rcon,rvs,re) = ralts n in altAnyR rcon rvs re)+{-# INLINE caseAltAnyR #-}++-- | Rewrite one child of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]+caseAltOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)+            => Rewrite c m CoreExpr+            -> Rewrite c m Id+            -> Rewrite c m Type+            -> (Int -> (Rewrite c m AltCon, (Int -> Rewrite c m Var), Rewrite c m CoreExpr))+            -> Rewrite c m CoreExpr+caseAltOneR rsc rw rty ralts = caseOneR rsc rw rty (\ n -> let (rcon,rvs,re) = ralts n in altOneR rcon rvs re)+{-# INLINE caseAltOneR #-}++---------------------------------------------------------------------+---------------------------------------------------------------------++-- Types++-- | Translate a type of the form: @TyVarTy@ 'TyVar'+tyVarT :: (ExtendPath c Crumb, Monad m) => Translate c m TyVar b -> Translate c m Type b+tyVarT t = translate $ \ c -> \case+                                 TyVarTy v -> apply t (c @@ TyVarTy_TyVar) v+                                 _         -> fail "not a type variable."+{-# INLINE tyVarT #-}++-- | Rewrite the 'TyVar' child of a type of the form: @TyVarTy@ 'TyVar'+tyVarR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyVar -> Rewrite c m Type+tyVarR r = tyVarT (TyVarTy <$> r)+{-# INLINE tyVarR #-}+++-- | Translate a type of the form: @LitTy@ 'TyLit'+litTyT :: (ExtendPath c Crumb, Monad m) => Translate c m TyLit b -> Translate c m Type b+litTyT t = translate $ \ c -> \case+                                 LitTy x -> apply t (c @@ LitTy_TyLit) x+                                 _       -> fail "not a type literal."+{-# INLINE litTyT #-}++-- | Rewrite the 'TyLit' child of a type of the form: @LitTy@ 'TyLit'+litTyR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyLit -> Rewrite c m Type+litTyR r = litTyT (LitTy <$> r)+{-# INLINE litTyR #-}+++-- | Translate a type of the form: @AppTy@ 'Type' 'Type'+appTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b+appTyT t1 t2 f = translate $ \ c -> \case+                                     AppTy ty1 ty2 -> f <$> apply t1 (c @@ AppTy_Fun) ty1 <*> apply t2 (c @@ AppTy_Arg) ty2+                                     _             -> fail "not a type application."+{-# INLINE appTyT #-}++-- | Rewrite all children of a type of the form: @AppTy@ 'Type' 'Type'+appTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type+appTyAllR r1 r2 = appTyT r1 r2 AppTy+{-# INLINE appTyAllR #-}++-- | Rewrite any children of a type of the form: @AppTy@ 'Type' 'Type'+appTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type+appTyAnyR r1 r2 = unwrapAnyR $ appTyAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE appTyAnyR #-}++-- | Rewrite one child of a type of the form: @AppTy@ 'Type' 'Type'+appTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type+appTyOneR r1 r2 = unwrapOneR $ appTyAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE appTyOneR #-}+++-- | Translate a type of the form: @FunTy@ 'Type' 'Type'+funTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b+funTyT t1 t2 f = translate $ \ c -> \case+                                     FunTy ty1 ty2 -> f <$> apply t1 (c @@ FunTy_Dom) ty1 <*> apply t2 (c @@ FunTy_CoDom) ty2+                                     _             -> fail "not a function type."+{-# INLINE funTyT #-}++-- | Rewrite all children of a type of the form: @FunTy@ 'Type' 'Type'+funTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type+funTyAllR r1 r2 = funTyT r1 r2 FunTy+{-# INLINE funTyAllR #-}++-- | Rewrite any children of a type of the form: @FunTy@ 'Type' 'Type'+funTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type+funTyAnyR r1 r2 = unwrapAnyR $ funTyAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE funTyAnyR #-}++-- | Rewrite one child of a type of the form: @FunTy@ 'Type' 'Type'+funTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type+funTyOneR r1 r2 = unwrapOneR $ funTyAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE funTyOneR #-}+++-- | Translate a type of the form: @ForAllTy@ 'Var' 'Type'+forAllTyT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b+forAllTyT t1 t2 f = translate $ \ c -> \case+                                          ForAllTy v ty -> f <$> apply t1 (c @@ ForAllTy_Var) v <*> apply t2 (addForallBinding v c @@ ForAllTy_Body) ty+                                          _             -> fail "not a forall type."+{-# INLINE forAllTyT #-}++-- | Rewrite all children of a type of the form: @ForAllTy@ 'Var' 'Type'+forAllTyAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type+forAllTyAllR r1 r2 = forAllTyT r1 r2 ForAllTy+{-# INLINE forAllTyAllR #-}++-- | Rewrite any children of a type of the form: @ForAllTy@ 'Var' 'Type'+forAllTyAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type+forAllTyAnyR r1 r2 = unwrapAnyR $ forAllTyAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE forAllTyAnyR #-}++-- | Rewrite one child of a type of the form: @ForAllTy@ 'Var' 'Type'+forAllTyOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type+forAllTyOneR r1 r2 = unwrapOneR $ forAllTyAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE forAllTyOneR #-}+++-- | Translate a type of the form: @TyConApp@ 'TyCon' ['KindOrType']+tyConAppT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m KindOrType a2) -> (a1 -> [a2] -> b) -> Translate c m Type b+tyConAppT t ts f = translate $ \ c -> \case+                                         TyConApp con tys -> f <$> apply t (c @@ TyConApp_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConApp_Arg n) ty | (ty,n) <- zip tys [0..] ]+                                         _                -> fail "not a type-constructor application."+{-# INLINE tyConAppT #-}++-- | Rewrite all children of a type of the form: @TyConApp@ 'TyCon' ['KindOrType']+tyConAppAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type+tyConAppAllR r rs = tyConAppT r rs TyConApp+{-# INLINE tyConAppAllR #-}++-- | Rewrite any children of a type of the form: @TyConApp@ 'TyCon' ['KindOrType']+tyConAppAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type+tyConAppAnyR r rs = unwrapAnyR $ tyConAppAllR (wrapAnyR r) (wrapAnyR . rs)+{-# INLINE tyConAppAnyR #-}++-- | Rewrite one child of a type of the form: @TyConApp@ 'TyCon' ['KindOrType']+tyConAppOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type+tyConAppOneR r rs = unwrapOneR $ tyConAppAllR (wrapOneR r) (wrapOneR . rs)+{-# INLINE tyConAppOneR #-}++---------------------------------------------------------------------+---------------------------------------------------------------------++-- Coercions+-- TODO: review and bring all these up-to-date for Coercions w/ Roles in 7.8++#if __GLASGOW_HASKELL__ > 706+-- | Translate a coercion of the form: @Refl@ 'Role' 'Type'+reflT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> (Role -> a1 -> b) -> Translate c m Coercion b+reflT t f = translate $ \ c -> \case+                                 Refl r ty -> f r <$> apply t (c @@ Refl_Type) ty+                                 _         -> fail "not a reflexive coercion."++-- | Rewrite the 'Type' child of a coercion of the form: @Refl@ 'Role' 'Type'+reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion+reflR r = reflT r Refl+#else+-- | Translate a coercion of the form: @Refl@ 'Type'+reflT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m Coercion b+reflT t = translate $ \ c -> \case+                                 Refl ty -> apply t (c @@ Refl_Type) ty+                                 _       -> fail "not a reflexive coercion."++-- | Rewrite the 'Type' child of a coercion of the form: @Refl@ 'Type'+reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion+reflR r = reflT (Refl <$> r)+#endif+{-# INLINE reflT #-}+{-# INLINE reflR #-}++#if __GLASGOW_HASKELL__ > 706+-- | Translate a coercion of the form: @TyConAppCo@ 'Role' 'TyCon' ['Coercion']+tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m Coercion a2) -> (Role -> a1 -> [a2] -> b) -> Translate c m Coercion b+tyConAppCoT t ts f = translate $ \ c -> \case+                                           TyConAppCo r con coes -> f r <$> apply t (c @@ TyConAppCo_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConAppCo_Arg n) co | (co,n) <- zip coes [0..] ]+                                           _                     -> fail "not a type-constructor coercion."+#else+-- | Translate a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']+tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b+tyConAppCoT t ts f = translate $ \ c -> \case+                                           TyConAppCo con coes -> f <$> apply t (c @@ TyConAppCo_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConAppCo_Arg n) co | (co,n) <- zip coes [0..] ]+                                           _                   -> fail "not a type-constructor coercion."+#endif+{-# INLINE tyConAppCoT #-}++-- | Rewrite all children of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']+tyConAppCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+tyConAppCoAllR r rs = tyConAppCoT r rs TyConAppCo+{-# INLINE tyConAppCoAllR #-}++-- | Rewrite any children of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']+tyConAppCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+tyConAppCoAnyR r rs = unwrapAnyR $ tyConAppCoAllR (wrapAnyR r) (wrapAnyR . rs)+{-# INLINE tyConAppCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']+tyConAppCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+tyConAppCoOneR r rs = unwrapOneR $ tyConAppCoAllR (wrapOneR r) (wrapOneR . rs)+{-# INLINE tyConAppCoOneR #-}+++-- | Translate a coercion of the form: @AppCo@ 'Coercion' 'Coercion'+appCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+appCoT t1 t2 f = translate $ \ c -> \case+                                     AppCo co1 co2 -> f <$> apply t1 (c @@ AppCo_Fun) co1 <*> apply t2 (c @@ AppCo_Arg) co2+                                     _             -> fail "not a coercion application."+{-# INLINE appCoT #-}++-- | Rewrite all children of a coercion of the form: @AppCo@ 'Coercion' 'Coercion'+appCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion+appCoAllR r1 r2 = appCoT r1 r2 AppCo+{-# INLINE appCoAllR #-}++-- | Rewrite any children of a coercion of the form: @AppCo@ 'Coercion' 'Coercion'+appCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion+appCoAnyR r1 r2 = unwrapAnyR $ appCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE appCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @AppCo@ 'Coercion' 'Coercion'+appCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion+appCoOneR r1 r2 = unwrapOneR $ appCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE appCoOneR #-}+++-- | Translate a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'+forAllCoT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m TyVar a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+forAllCoT t1 t2 f = translate $ \ c -> \case+                                          ForAllCo v co -> f <$> apply t1 (c @@ ForAllCo_TyVar) v <*> apply t2 (addForallBinding v c @@ ForAllCo_Body) co+                                          _             -> fail "not a forall coercion."+{-# INLINE forAllCoT #-}++-- | Rewrite all children of a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'+forAllCoAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion+forAllCoAllR r1 r2 = forAllCoT r1 r2 ForAllCo+{-# INLINE forAllCoAllR #-}++-- | Rewrite any children of a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'+forAllCoAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion+forAllCoAnyR r1 r2 = unwrapAnyR $ forAllCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE forAllCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'+forAllCoOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion+forAllCoOneR r1 r2 = unwrapOneR $ forAllCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE forAllCoOneR #-}+++-- | Translate a coercion of the form: @CoVarCo@ 'CoVar'+coVarCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoVar b -> Translate c m Coercion b+coVarCoT t = translate $ \ c -> \case+                                   CoVarCo v -> apply t (c @@ CoVarCo_CoVar) v+                                   _         -> fail "not a coercion variable."+{-# INLINE coVarCoT #-}++-- | Rewrite the 'CoVar' child of a coercion of the form: @CoVarCo@ 'CoVar'+coVarCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoVar -> Rewrite c m Coercion+coVarCoR r = coVarCoT (CoVarCo <$> r)+{-# INLINE coVarCoR #-}++#if __GLASGOW_HASKELL__ > 706+-- | Translate a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']+axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Translate c m (CoAxiom Branched) a1 -> Translate c m BranchIndex a2 -> (Int -> Translate c m Coercion a3) -> (a1 -> a2 -> [a3] -> b) -> Translate c m Coercion b+axiomInstCoT t1 t2 ts f = translate $ \ c -> \case+                                                AxiomInstCo ax idx coes -> f <$> apply t1 (c @@ AxiomInstCo_Axiom) ax <*> apply t2 (c @@ AxiomInstCo_Index) idx <*> sequence [ apply (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]+                                                _                       -> fail "not a coercion axiom instantiation."+#else+-- | Translate a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']+axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoAxiom a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b+axiomInstCoT t ts f = translate $ \ c -> \case+                                            AxiomInstCo ax coes -> f <$> apply t (c @@ AxiomInstCo_Axiom) ax <*> sequence [ apply (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]+                                            _                   -> fail "not a coercion axiom instantiation."+#endif+{-# INLINE axiomInstCoT #-}++#if __GLASGOW_HASKELL__ > 706+-- | Rewrite all children of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']+axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+axiomInstCoAllR r1 r2 rs = axiomInstCoT r1 r2 rs AxiomInstCo+#else+-- | Rewrite all children of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']+axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+axiomInstCoAllR r rs = axiomInstCoT r rs AxiomInstCo+#endif+{-# INLINE axiomInstCoAllR #-}++#if __GLASGOW_HASKELL__ > 706+-- | Rewrite any children of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']+axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+axiomInstCoAnyR r1 r2 rs = unwrapAnyR $ axiomInstCoAllR (wrapAnyR r1) (wrapAnyR r2) (wrapAnyR . rs)+#else+-- | Rewrite any children of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']+axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+axiomInstCoAnyR r rs = unwrapAnyR $ axiomInstCoAllR (wrapAnyR r) (wrapAnyR . rs)+#endif+{-# INLINE axiomInstCoAnyR #-}++#if __GLASGOW_HASKELL__ > 706+-- | Rewrite one child of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']+axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+axiomInstCoOneR r1 r2 rs = unwrapOneR $ axiomInstCoAllR (wrapOneR r1) (wrapOneR r2) (wrapOneR . rs)+#else+-- | Rewrite one child of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']+axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion+axiomInstCoOneR r rs = unwrapOneR $ axiomInstCoAllR (wrapOneR r) (wrapOneR . rs)+#endif+{-# INLINE axiomInstCoOneR #-}++#if __GLASGOW_HASKELL__ > 706+#else+-- | Translate a coercion of the form: @UnsafeCo@ 'Type' 'Type'+unsafeCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+unsafeCoT t1 t2 f = translate $ \ c -> \case+                                          UnsafeCo ty1 ty2 -> f <$> apply t1 (c @@ UnsafeCo_Left) ty1 <*> apply t2 (c @@ UnsafeCo_Right) ty2+                                          _                -> fail "not an unsafe coercion."+{-# INLINE unsafeCoT #-}++-- | Rewrite all children of a coercion of the form: @UnsafeCo@ 'Type' 'Type'+unsafeCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion+unsafeCoAllR r1 r2 = unsafeCoT r1 r2 UnsafeCo+{-# INLINE unsafeCoAllR #-}++-- | Rewrite any children of a coercion of the form: @UnsafeCo@ 'Type' 'Type'+unsafeCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion+unsafeCoAnyR r1 r2 = unwrapAnyR $ unsafeCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE unsafeCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @UnsafeCo@ 'Type' 'Type'+unsafeCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion+unsafeCoOneR r1 r2 = unwrapOneR $ unsafeCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE unsafeCoOneR #-}+#endif++-- | Translate a coercion of the form: @SymCo@ 'Coercion'+symCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m Coercion b+symCoT t = translate $ \ c -> \case+                                   SymCo co -> apply t (c @@ SymCo_Co) co+                                   _        -> fail "not a symmetric coercion."+{-# INLINE symCoT #-}++-- | Rewrite the 'Coercion' child of a coercion of the form: @SymCo@ 'Coercion'+symCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion+symCoR r = symCoT (SymCo <$> r)+{-# INLINE symCoR #-}+++-- | Translate a coercion of the form: @TransCo@ 'Coercion' 'Coercion'+transCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+transCoT t1 t2 f = translate $ \ c -> \case+                                          TransCo co1 co2 -> f <$> apply t1 (c @@ TransCo_Left) co1 <*> apply t2 (c @@ TransCo_Right) co2+                                          _               -> fail "not a transitive coercion."+{-# INLINE transCoT #-}++-- | Rewrite all children of a coercion of the form: @TransCo@ 'Coercion' 'Coercion'+transCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion+transCoAllR r1 r2 = transCoT r1 r2 TransCo+{-# INLINE transCoAllR #-}++-- | Rewrite any children of a coercion of the form: @TransCo@ 'Coercion' 'Coercion'+transCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion+transCoAnyR r1 r2 = unwrapAnyR $ transCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE transCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @TransCo@ 'Coercion' 'Coercion'+transCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion+transCoOneR r1 r2 = unwrapOneR $ transCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE transCoOneR #-}+++-- | Translate a coercion of the form: @NthCo@ 'Int' 'Coercion'+nthCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Int a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+nthCoT t1 t2 f = translate $ \ c -> \case+                                          NthCo n co -> f <$> apply t1 (c @@ NthCo_Int) n <*> apply t2 (c @@ NthCo_Co) co+                                          _          -> fail "not an Nth coercion."+{-# INLINE nthCoT #-}++-- | Rewrite all children of a coercion of the form: @NthCo@ 'Int' 'Coercion'+nthCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion+nthCoAllR r1 r2 = nthCoT r1 r2 NthCo+{-# INLINE nthCoAllR #-}++-- | Rewrite any children of a coercion of the form: @NthCo@ 'Int' 'Coercion'+nthCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion+nthCoAnyR r1 r2 = unwrapAnyR $ nthCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE nthCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @NthCo@ 'Int' 'Coercion'+nthCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion+nthCoOneR r1 r2 = unwrapOneR $ nthCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE nthCoOneR #-}+++#if __GLASGOW_HASKELL__ > 706+-- | Translate a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'+lrCoT :: (ExtendPath c Crumb, Monad m) => Translate c m LeftOrRight a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+lrCoT t1 t2 f = translate $ \ c -> \case+                                      LRCo lr co -> f <$> apply t1 (c @@ LRCo_LR) lr <*> apply t2 (c @@ LRCo_Co) co+                                      _          -> fail "not a left/right coercion."+{-# INLINE lrCoT #-}++-- | Translate all children of a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'+lrCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion+lrCoAllR r1 r2 = lrCoT r1 r2 LRCo+{-# INLINE lrCoAllR #-}++-- | Translate any children of a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'+lrCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion+lrCoAnyR r1 r2 = unwrapAnyR $ lrCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE lrCoAnyR #-}++-- | Translate one child of a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'+lrCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion+lrCoOneR r1 r2 = unwrapOneR $ lrCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE lrCoOneR #-}+#else+#endif+++-- | Translate a coercion of the form: @InstCo@ 'Coercion' 'Type'+instCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b+instCoT t1 t2 f = translate $ \ c -> \case+                                          InstCo co ty -> f <$> apply t1 (c @@ InstCo_Co) co <*> apply t2 (c @@ InstCo_Type) ty+                                          _            -> fail "not a coercion instantiation."+{-# INLINE instCoT #-}++-- | Rewrite all children of a coercion of the form: @InstCo@ 'Coercion' 'Type'+instCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion+instCoAllR r1 r2 = instCoT r1 r2 InstCo+{-# INLINE instCoAllR #-}++-- | Rewrite any children of a coercion of the form: @InstCo@ 'Coercion' 'Type'+instCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion+instCoAnyR r1 r2 = unwrapAnyR $ instCoAllR (wrapAnyR r1) (wrapAnyR r2)+{-# INLINE instCoAnyR #-}++-- | Rewrite one child of a coercion of the form: @InstCo@ 'Coercion' 'Type'+instCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion+instCoOneR r1 r2 = unwrapOneR $ instCoAllR (wrapOneR r1) (wrapOneR r2)+{-# INLINE instCoOneR #-}++---------------------------------------------------------------------+---------------------------------------------------------------------++-- | Earlier versions of HERMIT used 'Int' as the crumb type.+--   This translation maps an 'Int' to the corresponding 'Crumb', for backwards compatibility purposes.+deprecatedIntToCrumbT :: Monad m => Int -> Translate c m Core Crumb+deprecatedIntToCrumbT n = contextfreeT $ \case+                                            GutsCore _                 | n == 0                        -> return ModGuts_Prog+                                            AltCore _                  | n == 0                        -> return Alt_RHS+                                            DefCore _                  | n == 0                        -> return Def_RHS+                                            ProgCore (ProgCons _ _)    | n == 0                        -> return ProgCons_Head+                                                                       | n == 1                        -> return ProgCons_Tail+                                            BindCore (NonRec _ _)      | n == 0                        -> return NonRec_RHS+                                            BindCore (Rec bds)         | (n >= 0) && (n < length bds)  -> return (Rec_Def n)+                                            ExprCore (App _ _)         | n == 0                        -> return App_Fun+                                                                       | n == 1                        -> return App_Arg+                                            ExprCore (Lam _ _)         | n == 0                        -> return Lam_Body+                                            ExprCore (Let _ _)         | n == 0                        -> return Let_Bind+                                                                       | n == 1                        -> return Let_Body+                                            ExprCore (Case _ _ _ alts) | n == 0                        -> return Case_Scrutinee+                                                                       | (n > 0) && (n <= length alts) -> return (Case_Alt (n-1))+                                            ExprCore (Cast _ _)        | n == 0                        -> return Cast_Expr+                                            ExprCore (Tick _ _)        | n == 0                        -> return Tick_Expr+                                            _                                                          -> fail ("Child " ++ show n ++ " does not exist.")+{-# INLINE deprecatedIntToCrumbT #-}++-- | Builds a path to the first child, based on the old numbering system.+deprecatedIntToPathT :: Monad m => Int -> Translate c m Core LocalPathH+deprecatedIntToPathT =  liftM (mempty @@) . deprecatedIntToCrumbT+{-# INLINE deprecatedIntToPathT #-}++---------------------------------------------------------------------+---------------------------------------------------------------------
+ src/HERMIT/Kure/SumTypes.hs view
@@ -0,0 +1,453 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, InstanceSigs, LambdaCase #-}++module HERMIT.Kure.SumTypes+  ( -- * Sum Types+    Core(..)+  , TyCo(..)+  , CoreTC(..)+  -- * Equality+  -- ** Syntactic Equality+  , coreSyntaxEq+  , tyCoSyntaxEq+  , coreTCSyntaxEq+  -- ** Alpha Equality+  , coreAlphaEq+  , tyCoAlphaEq+  , coreTCAlphaEq+  -- ** Collecting Free Variables+  , freeVarsCore+  , freeVarsTyCo+  , freeVarsCoreTC+  -- * Promotion Combinators+  -- ** Translate Promotions+  , promoteModGutsT+  , promoteProgT+  , promoteBindT+  , promoteDefT+  , promoteExprT+  , promoteAltT+  , promoteTypeT+  , promoteCoercionT+  -- ** Rewrite Promotions+  , promoteModGutsR+  , promoteProgR+  , promoteBindR+  , promoteDefR+  , promoteExprR+  , promoteAltR+  , promoteTypeR+  , promoteCoercionR+  -- ** BiRewrite Promotions+  , promoteExprBiR+  )+where++import Language.KURE.Translate+import Language.KURE.Injection+import Language.KURE.BiTranslate++import HERMIT.Core+import HERMIT.GHC++---------------------------------------------------------------------++-- | Core is a sum type for use by KURE.  Core = ModGuts + CoreProg + CoreBind + CoreDef + CoreExpr + CoreAlt+data Core = GutsCore  ModGuts            -- ^ The module.+          | ProgCore  CoreProg           -- ^ A program (a telescope of top-level binding groups).+          | BindCore  CoreBind           -- ^ A binding group.+          | DefCore   CoreDef            -- ^ A recursive definition.+          | ExprCore  CoreExpr           -- ^ An expression.+          | AltCore   CoreAlt            -- ^ A case alternative.++-- | TyCo is a sum type for use by KURE.  TyCo = Type + Coercion+data TyCo = TypeCore Type                -- ^ A type.+          | CoercionCore Coercion        -- ^ A coercion.++-- | CoreTC is a sum type for use by KURE.  CoreTC = Core + TyCo+data CoreTC = Core Core+            | TyCo TyCo++---------------------------------------------------------------------++-- | Alpha equality of 'Core' fragments.+coreAlphaEq :: Core -> Core -> Bool+coreAlphaEq (GutsCore g1) (GutsCore g2) = progAlphaEq (bindsToProg $ mg_binds g1) (bindsToProg $ mg_binds g2)+coreAlphaEq (ProgCore p1) (ProgCore p2) = progAlphaEq p1 p2+coreAlphaEq (BindCore b1) (BindCore b2) = bindAlphaEq b1 b2+coreAlphaEq (DefCore d1)  (DefCore d2)  = defAlphaEq d1 d2+coreAlphaEq (ExprCore e1) (ExprCore e2) = exprAlphaEq e1 e2+coreAlphaEq (AltCore a1)  (AltCore a2)  = altAlphaEq a1 a2+coreAlphaEq _             _             = False++-- | Alpha equality of 'TyCo' fragments.+tyCoAlphaEq :: TyCo -> TyCo -> Bool+tyCoAlphaEq (TypeCore ty1)     (TypeCore ty2)     = typeAlphaEq ty1 ty2+tyCoAlphaEq (CoercionCore co1) (CoercionCore co2) = coercionAlphaEq co1 co2+tyCoAlphaEq _                  _                  = False++-- | Alpha equality of 'CoreTC' fragments.+coreTCAlphaEq :: CoreTC -> CoreTC -> Bool+coreTCAlphaEq (Core c1)  (Core c2)  = coreAlphaEq c1 c2+coreTCAlphaEq (TyCo tc1) (TyCo tc2) = tyCoAlphaEq tc1 tc2+coreTCAlphaEq _          _          = False++---------------------------------------------------------------------++-- | Syntactic equality of 'Core' fragments.+coreSyntaxEq :: Core -> Core -> Bool+coreSyntaxEq (GutsCore g1) (GutsCore g2) = all2 bindSyntaxEq (mg_binds g1) (mg_binds g2)+coreSyntaxEq (ProgCore p1) (ProgCore p2) = progSyntaxEq p1 p2+coreSyntaxEq (BindCore b1) (BindCore b2) = bindSyntaxEq b1 b2+coreSyntaxEq (DefCore d1)  (DefCore d2)  = defSyntaxEq d1 d2+coreSyntaxEq (ExprCore e1) (ExprCore e2) = exprSyntaxEq e1 e2+coreSyntaxEq (AltCore a1)  (AltCore a2)  = altSyntaxEq a1 a2+coreSyntaxEq _             _             = False++-- | Syntactic equality of 'TyCo' fragments.+tyCoSyntaxEq :: TyCo -> TyCo -> Bool+tyCoSyntaxEq (TypeCore ty1)     (TypeCore ty2)     = typeSyntaxEq ty1 ty2+tyCoSyntaxEq (CoercionCore co1) (CoercionCore co2) = coercionSyntaxEq co1 co2+tyCoSyntaxEq _                  _                  = False++-- | Syntactic equality of 'CoreTC' fragments.+coreTCSyntaxEq :: CoreTC -> CoreTC -> Bool+coreTCSyntaxEq (Core c1)  (Core c2)  = coreSyntaxEq c1 c2+coreTCSyntaxEq (TyCo tc1) (TyCo tc2) = tyCoSyntaxEq tc1 tc2+coreTCSyntaxEq _          _          = False++---------------------------------------------------------------------++-- | Find all free variables in a 'Core' node.+freeVarsCore :: Core -> VarSet+freeVarsCore = \case+                  GutsCore g -> freeVarsProg (bindsToProg $ mg_binds g)+                  ProgCore p -> freeVarsProg p+                  BindCore b -> freeVarsBind b+                  DefCore d  -> freeVarsDef d+                  ExprCore e -> freeVarsExpr e+                  AltCore a  -> freeVarsAlt a++-- | Find all free variables in a 'TyCo' node.+freeVarsTyCo :: TyCo -> VarSet+freeVarsTyCo = \case+                  TypeCore ty     -> tyVarsOfType ty+                  CoercionCore co -> tyCoVarsOfCo co++-- | Find all free variables in a 'CoreTC' node.+freeVarsCoreTC :: CoreTC -> VarSet+freeVarsCoreTC = \case+                    TyCo tyco -> freeVarsTyCo tyco+                    Core core -> freeVarsCore core++---------------------------------------------------------------------++instance Injection ModGuts Core where++  inject :: ModGuts -> Core+  inject = GutsCore+  {-# INLINE inject #-}++  project :: Core -> Maybe ModGuts+  project (GutsCore guts) = Just guts+  project _               = Nothing+  {-# INLINE project #-}+++instance Injection CoreProg Core where++  inject :: CoreProg -> Core+  inject = ProgCore+  {-# INLINE inject #-}++  project :: Core -> Maybe CoreProg+  project (ProgCore bds) = Just bds+  project _              = Nothing+  {-# INLINE project #-}+++instance Injection CoreBind Core where++  inject :: CoreBind -> Core+  inject = BindCore+  {-# INLINE inject #-}++  project :: Core -> Maybe CoreBind+  project (BindCore bnd)  = Just bnd+  project _               = Nothing+  {-# INLINE project #-}+++instance Injection CoreDef Core where++  inject :: CoreDef -> Core+  inject = DefCore+  {-# INLINE inject #-}++  project :: Core -> Maybe CoreDef+  project (DefCore def) = Just def+  project _             = Nothing+  {-# INLINE project #-}+++instance Injection CoreAlt Core where++  inject :: CoreAlt -> Core+  inject = AltCore+  {-# INLINE inject #-}++  project :: Core -> Maybe CoreAlt+  project (AltCore expr) = Just expr+  project _              = Nothing+  {-# INLINE project #-}+++instance Injection CoreExpr Core where++  inject :: CoreExpr -> Core+  inject = ExprCore+  {-# INLINE inject #-}++  project :: Core -> Maybe CoreExpr+  project (ExprCore expr) = Just expr+  project _               = Nothing+  {-# INLINE project #-}++---------------------------------------------------------------------++instance Injection Type TyCo where++  inject :: Type -> TyCo+  inject = TypeCore+  {-# INLINE inject #-}++  project :: TyCo -> Maybe Type+  project (TypeCore ty) = Just ty+  project _             = Nothing+  {-# INLINE project #-}+++instance Injection Coercion TyCo where++  inject :: Coercion -> TyCo+  inject = CoercionCore+  {-# INLINE inject #-}++  project :: TyCo -> Maybe Coercion+  project (CoercionCore ty) = Just ty+  project _                 = Nothing+  {-# INLINE project #-}++---------------------------------------------------------------------++instance Injection Core CoreTC where++  inject :: Core -> CoreTC+  inject = Core+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe Core+  project (Core core) = Just core+  project _           = Nothing+  {-# INLINE project #-}+++instance Injection TyCo CoreTC where++  inject :: TyCo -> CoreTC+  inject = TyCo+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe TyCo+  project (TyCo tyCo) = Just tyCo+  project _           = Nothing+  {-# INLINE project #-}++---------------------------------------------------------------------++instance Injection ModGuts CoreTC where++  inject :: ModGuts -> CoreTC+  inject = Core . GutsCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe ModGuts+  project (Core (GutsCore guts)) = Just guts+  project _                      = Nothing+  {-# INLINE project #-}+++instance Injection CoreProg CoreTC where++  inject :: CoreProg -> CoreTC+  inject = Core . ProgCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe CoreProg+  project (Core (ProgCore bds)) = Just bds+  project _                     = Nothing+  {-# INLINE project #-}+++instance Injection CoreBind CoreTC where++  inject :: CoreBind -> CoreTC+  inject = Core . BindCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe CoreBind+  project (Core (BindCore bnd))  = Just bnd+  project _                      = Nothing+  {-# INLINE project #-}+++instance Injection CoreDef CoreTC where++  inject :: CoreDef -> CoreTC+  inject = Core . DefCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe CoreDef+  project (Core (DefCore def)) = Just def+  project _                    = Nothing+  {-# INLINE project #-}+++instance Injection CoreAlt CoreTC where++  inject :: CoreAlt -> CoreTC+  inject = Core . AltCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe CoreAlt+  project (Core (AltCore expr)) = Just expr+  project _                     = Nothing+  {-# INLINE project #-}+++instance Injection CoreExpr CoreTC where++  inject :: CoreExpr -> CoreTC+  inject = Core . ExprCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe CoreExpr+  project (Core (ExprCore expr)) = Just expr+  project _                      = Nothing+  {-# INLINE project #-}+++instance Injection Type CoreTC where++  inject :: Type -> CoreTC+  inject = TyCo . TypeCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe Type+  project (TyCo (TypeCore ty)) = Just ty+  project _                    = Nothing+  {-# INLINE project #-}+++instance Injection Coercion CoreTC where++  inject :: Coercion -> CoreTC+  inject = TyCo . CoercionCore+  {-# INLINE inject #-}++  project :: CoreTC -> Maybe Coercion+  project (TyCo (CoercionCore ty)) = Just ty+  project _                        = Nothing+  {-# INLINE project #-}++---------------------------------------------------------------------++-- | Promote a translate on 'ModGuts'.+promoteModGutsT :: (Monad m, Injection ModGuts g) => Translate c m ModGuts b -> Translate c m g b+promoteModGutsT = promoteWithFailMsgT "This translate can only succeed at the module level."+{-# INLINE promoteModGutsT #-}++-- | Promote a translate on 'CoreProg'.+promoteProgT :: (Monad m, Injection CoreProg g) => Translate c m CoreProg b -> Translate c m g b+promoteProgT = promoteWithFailMsgT "This translate can only succeed at program nodes (the top-level)."+{-# INLINE promoteProgT #-}++-- | Promote a translate on 'CoreBind'.+promoteBindT :: (Monad m, Injection CoreBind g) => Translate c m CoreBind b -> Translate c m g b+promoteBindT = promoteWithFailMsgT "This translate can only succeed at binding group nodes."+{-# INLINE promoteBindT #-}++-- | Promote a translate on 'CoreDef'.+promoteDefT :: (Monad m, Injection CoreDef g) => Translate c m CoreDef b -> Translate c m g b+promoteDefT = promoteWithFailMsgT "This translate can only succeed at recursive definition nodes."+{-# INLINE promoteDefT #-}++-- | Promote a translate on 'CoreAlt'.+promoteAltT :: (Monad m, Injection CoreAlt g) => Translate c m CoreAlt b -> Translate c m g b+promoteAltT = promoteWithFailMsgT "This translate can only succeed at case alternative nodes."+{-# INLINE promoteAltT #-}++-- | Promote a translate on 'CoreExpr'.+promoteExprT :: (Monad m, Injection CoreExpr g) => Translate c m CoreExpr b -> Translate c m g b+promoteExprT = promoteWithFailMsgT "This translate can only succeed at expression nodes."+{-# INLINE promoteExprT #-}++-- | Promote a translate on 'Type'.+promoteTypeT :: (Monad m, Injection Type g) => Translate c m Type b -> Translate c m g b+promoteTypeT = promoteWithFailMsgT "This translate can only succeed at type nodes."+{-# INLINE promoteTypeT #-}++-- | Promote a translate on 'Coercion'.+promoteCoercionT :: (Monad m, Injection Coercion g) => Translate c m Coercion b -> Translate c m g b+promoteCoercionT = promoteWithFailMsgT "This translate can only succeed at coercion nodes."+{-# INLINE promoteCoercionT #-}++---------------------------------------------------------------------++-- | Promote a rewrite on 'ModGuts'.+promoteModGutsR :: (Monad m, Injection ModGuts g) => Rewrite c m ModGuts -> Rewrite c m g+promoteModGutsR = promoteWithFailMsgR "This rewrite can only succeed at the module level."+{-# INLINE promoteModGutsR #-}++-- | Promote a rewrite on 'CoreProg'.+promoteProgR :: (Monad m, Injection CoreProg g) => Rewrite c m CoreProg -> Rewrite c m g+promoteProgR = promoteWithFailMsgR "This rewrite can only succeed at program nodes (the top-level)."+{-# INLINE promoteProgR #-}++-- | Promote a rewrite on 'CoreBind'.+promoteBindR :: (Monad m, Injection CoreBind g) => Rewrite c m CoreBind -> Rewrite c m g+promoteBindR = promoteWithFailMsgR "This rewrite can only succeed at binding group nodes."+{-# INLINE promoteBindR #-}++-- | Promote a rewrite on 'CoreDef'.+promoteDefR :: (Monad m, Injection CoreDef g) => Rewrite c m CoreDef -> Rewrite c m g+promoteDefR = promoteWithFailMsgR "This rewrite can only succeed at recursive definition nodes."+{-# INLINE promoteDefR #-}++-- | Promote a rewrite on 'CoreAlt'.+promoteAltR :: (Monad m, Injection CoreAlt g) => Rewrite c m CoreAlt -> Rewrite c m g+promoteAltR = promoteWithFailMsgR "This rewrite can only succeed at case alternative nodes."+{-# INLINE promoteAltR #-}++-- | Promote a rewrite on 'CoreExpr'.+promoteExprR :: (Monad m, Injection CoreExpr g) => Rewrite c m CoreExpr -> Rewrite c m g+promoteExprR = promoteWithFailMsgR "This rewrite can only succeed at expression nodes."+{-# INLINE promoteExprR #-}++-- | Promote a rewrite on 'Type'.+promoteTypeR :: (Monad m, Injection Type g) => Rewrite c m Type -> Rewrite c m g+promoteTypeR = promoteWithFailMsgR "This rewrite can only succeed at type nodes."+{-# INLINE promoteTypeR #-}++-- | Promote a rewrite on 'Coercion'.+promoteCoercionR :: (Monad m, Injection Coercion g) => Rewrite c m Coercion -> Rewrite c m g+promoteCoercionR = promoteWithFailMsgR "This rewrite can only succeed at coercion nodes."+{-# INLINE promoteCoercionR #-}++---------------------------------------------------------------------++-- | Promote a bidirectional rewrite on 'CoreExpr'.+promoteExprBiR :: (Monad m, Injection CoreExpr g) => BiRewrite c m CoreExpr -> BiRewrite c m g+promoteExprBiR b = bidirectional (promoteExprR $ forwardT b) (promoteExprR $ backwardT b)+{-# INLINE promoteExprBiR #-}++---------------------------------------------------------------------
+ src/HERMIT/Monad.hs view
@@ -0,0 +1,176 @@+{-# LANGUAGE CPP, InstanceSigs #-}++module HERMIT.Monad+          (+            -- * The HERMIT Monad+            HermitM+          , runHM+          , liftCoreM+          , newGlobalIdH+          , newIdH+          , newTyVarH+          , newCoVarH+          , cloneVarH+            -- * Saving Definitions+          , Label+          , DefStash+          , saveDef+          , lookupDef+          , getStash+            -- * Messages+          , HermitMEnv(..)+          , DebugMessage(..)+          , mkHermitMEnv+          , sendDebugMessage+) where++import Prelude hiding (lookup)++import Data.Map++import Control.Monad+import Control.Monad.IO.Class+import Control.Applicative+import Control.Arrow++import Language.KURE++import HERMIT.Core+import HERMIT.Context+import HERMIT.Kure.SumTypes+import HERMIT.GHC++----------------------------------------------------------------------------++-- | A label for individual definitions.+type Label = String++-- | A store of saved definitions.+type DefStash = Map Label CoreDef++-- | A way of sending messages to top level+newtype HermitMEnv = HermitMEnv { hs_debugChan :: DebugMessage -> HermitM () }++-- | The HERMIT monad is kept abstract.+newtype HermitM a = HermitM (HermitMEnv -> DefStash -> CoreM (KureM (DefStash, a)))++runHermitM :: HermitM a -> HermitMEnv -> DefStash -> CoreM (KureM (DefStash, a))+runHermitM (HermitM f) = f++-- | Eliminator for 'HermitM'.+runHM :: HermitMEnv -> DefStash -> (DefStash -> a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b+runHM env s success failure ma = runHermitM ma env s >>= runKureM (\ (a,b) -> success a b) failure++----------------------------------------------------------------------------++-- | Get the stash of saved definitions.+getStash :: HermitM DefStash+getStash = HermitM (\ _ s -> return $ return (s, s))++-- | Replace the stash of saved definitions.+putStash :: DefStash -> HermitM ()+putStash s = HermitM (\ _ _ -> return $ return (s, ()))++sendDebugMessage :: DebugMessage -> HermitM ()+sendDebugMessage msg = do env <- HermitM $ \ ch s -> return $ return (s, ch)+                          hs_debugChan env msg++-- | Save a definition for future use.+saveDef :: Label -> CoreDef -> HermitM ()+saveDef l d = getStash >>= (insert l d >>> putStash)++-- | Lookup a previously saved definition.+lookupDef :: Label -> HermitM CoreDef+lookupDef l = getStash >>= (lookup l >>> maybe (fail "Definition not found.") return)++----------------------------------------------------------------------------++instance Functor HermitM where+  fmap :: (a -> b) -> HermitM a -> HermitM b+  fmap = liftM++instance Applicative HermitM where+  pure :: a -> HermitM a+  pure = return++  (<*>) :: HermitM (a -> b) -> HermitM a -> HermitM b+  (<*>) = ap++instance Monad HermitM where+  return :: a -> HermitM a+  return a = HermitM $ \ _ s -> return (return (s,a))++  (>>=) :: HermitM a -> (a -> HermitM b) -> HermitM b+  (HermitM gcm) >>= f = HermitM $ \ env -> gcm env >=> runKureM (\ (s', a) -> runHermitM (f a) env s') (return . fail)++  fail :: String -> HermitM a+  fail msg = HermitM $ \ _ _ -> return (fail msg)++instance MonadCatch HermitM where+  catchM :: HermitM a -> (String -> HermitM a) -> HermitM a+  (HermitM gcm) `catchM` f = HermitM $ \ env s -> gcm env s >>= runKureM (return.return) (\ msg -> runHermitM (f msg) env s)++----------------------------------------------------------------------------++-- | 'CoreM' can be lifted to 'HermitM'.+liftCoreM :: CoreM a -> HermitM a+liftCoreM ma = HermitM $ \ _ s -> do a <- ma+                                     return (return (s,a))++instance MonadIO HermitM where+  liftIO :: IO a -> HermitM a+  liftIO = liftCoreM . liftIO++instance MonadUnique HermitM where+  getUniqueSupplyM :: HermitM UniqSupply+  getUniqueSupplyM = liftCoreM getUniqueSupplyM++instance MonadThings HermitM where+  lookupThing :: Name -> HermitM TyThing+  lookupThing = liftCoreM . lookupThing++instance HasDynFlags HermitM where+  getDynFlags :: HermitM DynFlags+  getDynFlags = liftCoreM getDynFlags++----------------------------------------------------------------------------++newName :: String -> HermitM Name+newName nm = mkSystemVarName <$> getUniqueM <*> pure (mkFastString nm)++-- | Make a unique global identifier for a specified type, using a provided name.+newGlobalIdH :: String -> Type -> HermitM Id+newGlobalIdH nm ty = mkVanillaGlobal <$> newName nm <*> pure ty++-- | Make a unique identifier for a specified type, using a provided name.+newIdH :: String -> Type -> HermitM Id+newIdH nm ty = mkLocalId <$> newName nm <*> pure ty++-- | Make a unique type variable for a specified kind, using a provided name.+newTyVarH :: String -> Kind -> HermitM TyVar+newTyVarH nm k = mkTyVar <$> newName nm <*> pure k++-- | Make a unique coercion variable for a specified type, using a provided name.+newCoVarH :: String -> Type -> HermitM TyVar+newCoVarH nm ty = mkCoVar <$> newName nm <*> pure ty++-- | Make a new variable of the same type, with a modified textual name.+cloneVarH :: (String -> String) -> Var -> HermitM Var+cloneVarH nameMod v | isTyVar v = newTyVarH name ty+                    | isCoVar v = newCoVarH name ty+                    | isId v    = newIdH name ty+                    | otherwise = fail "If this variable isn't a type, coercion or identifier, then what is it?"+  where+    name = nameMod (uqName v)+    ty   = varType v++----------------------------------------------------------------------------++-- | A message packet.+data DebugMessage = DebugTick String+                  | DebugCore String HermitC CoreTC++mkHermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv+mkHermitMEnv debugger = HermitMEnv { hs_debugChan = debugger }++----------------------------------------------------------------------------
+ src/HERMIT/Optimize.hs view
@@ -0,0 +1,214 @@+{-# LANGUAGE KindSignatures, GADTs, FlexibleContexts, GeneralizedNewtypeDeriving, LambdaCase #-}+module HERMIT.Optimize+    ( -- * The HERMIT Plugin+      optimize+      -- ** Running translations+    , query+    , run+      -- ** Using the shell+    , interactive+    , display+    , setPretty+    , setPrettyOptions+      -- ** Active modifiers+    , at+    , phase+    , after+    , before+    , allPhases+    , firstPhase+    , lastPhase+      -- ** Types+    , OM+    , omToIO+    ) where++import Control.Arrow+import Control.Concurrent.STM+import Control.Monad.Error hiding (guard)+import Control.Monad.Operational+import Control.Monad.State hiding (guard)++import Data.Default+import Data.Monoid+import qualified Data.Map as M++import HERMIT.Dictionary+import HERMIT.External hiding (Query, Shell)+import HERMIT.Kernel.Scoped+import HERMIT.Context+import HERMIT.Kure+import HERMIT.GHC hiding (singleton, liftIO, display, (<>))+import qualified HERMIT.GHC as GHC+import HERMIT.Monad+import HERMIT.Plugin+import HERMIT.PrettyPrinter.Common+import qualified HERMIT.PrettyPrinter.Clean as Clean+import HERMIT.Shell.Command+import HERMIT.Shell.Types++import System.Console.Haskeline (defaultBehavior)++data OInst :: * -> * where+    Shell    :: [External] -> [CommandLineOption] -> OInst ()+    Guard    :: (PhaseInfo -> Bool) -> OM ()      -> OInst ()+    Focus    :: (Injection ModGuts g, Walker HermitC g) => TranslateH g LocalPathH -> OM a -> OInst a+    RR       :: (Injection ModGuts g, Walker HermitC g) => RewriteH g                      -> OInst ()+    Query    :: (Injection ModGuts g, Walker HermitC g) => TranslateH g a                  -> OInst a++newtype OM a = OM (ProgramT OInst (CLM IO) a)+    deriving (Monad, MonadIO)++optimize :: ([CommandLineOption] -> OM ()) -> Plugin+optimize f = hermitPlugin $ \ phaseInfo -> runOM phaseInfo . f++runOM :: PhaseInfo -> OM () -> ModGuts -> CoreM ModGuts+runOM phaseInfo opt = scopedKernel $ \ kernel initSAST -> do+    tick <- liftIO $ atomically $ newTVar M.empty+    let initState = CommandLineState+                       { cl_cursor         = initSAST+                       , cl_pretty         = Clean.ppCoreTC+                       , cl_pretty_opts    = def { po_width = 80 }+                       , cl_render         = unicodeConsole+                       , cl_height         = 30+                       , cl_nav            = False+                       , cl_running_script = False+                       , cl_tick          = tick+                       , cl_corelint      = False+                       , cl_failhard      = False+                       , cl_window        = mempty+                       , cl_dict          = error "cl_dict" -- TODO+                       , cl_scripts       = []+                       , cl_kernel        = kernel+                       , cl_initSAST      = initSAST+                       , cl_version       = VersionStore+                                              { vs_graph = []+                                              , vs_tags  = []+                                              }+                       }++    (r,st) <- omToIO initState phaseInfo opt+    either (\case CLAbort         -> abortS kernel+                  CLResume   sast -> resumeS kernel sast+                  CLContinue _    -> putStrLn "Uncaught CLContinue! Aborting..." >> abortS kernel+                  CLError    err  -> putStrLn err >> abortS kernel)+           (\ _ -> resumeS kernel $ cl_cursor st) r++-- TODO - better name!+omToIO :: CommandLineState -> PhaseInfo -> OM a -> IO (Either CLException a, CommandLineState)+omToIO initState phaseInfo (OM opt) = runCLM initState (eval phaseInfo opt)++eval :: PhaseInfo -> ProgramT OInst (CLM IO) a -> CLM IO a+eval phaseInfo comp = do+    (kernel, env) <- gets $ cl_kernel &&& cl_kernel_env+    v <- viewT comp+    case v of+        Return x            -> return x+        RR rr       :>>= k  -> runS (applyS kernel rr env) >>= eval phaseInfo . k+        Query tr    :>>= k  -> runK (queryS kernel tr env) >>= eval phaseInfo . k+        Shell es os :>>= k -> do+            -- We want to discard the current focus, open the shell at+            -- the top level, then restore the current focus.+            paths <- resetScoping env+            catchContinue (commandLine os defaultBehavior es)+            _ <- resetScoping env+            restoreScoping env paths+            eval phaseInfo $ k ()+        Guard p (OM m)  :>>= k  -> when (p phaseInfo) (eval phaseInfo m) >>= eval phaseInfo . k+        Focus tp (OM m) :>>= k  -> do+            sast <- gets cl_cursor+            p <- queryS kernel tp env sast    -- run the pathfinding translation+            runS $ beginScopeS kernel         -- remember the current path+            runS $ modPathS kernel (<> p) env -- modify the current path+            r <- eval phaseInfo m             -- run the focused computation+            runS $ endScopeS kernel           -- endscope on it, so we go back to where we started+            eval phaseInfo $ k r++------------------------- Shell-related helpers --------------------------------------++catchContinue :: Monad m => CLM m () -> CLM m ()+catchContinue m = catchError m (\case CLContinue st -> put st+                                      other -> throwError other)++resetScoping :: HermitMEnv -> CLM IO [PathH]+resetScoping env = do+    kernel <- gets cl_kernel+    paths <- runK $ pathS kernel+    replicateM_ (length paths - 1) $ runS $ endScopeS kernel+    -- modPathS commonly fails here because the path is unchanged, so throw away failures+    catchM (runS $ modPathS kernel (const mempty) env) (const (return ()))+    return paths++restoreScoping :: HermitMEnv -> [PathH] -> CLM IO ()+restoreScoping _   []    = return ()+restoreScoping env (h:t) = do+    kernel <- gets cl_kernel++    let go p []      = restore p+        go p (p':ps) = restore p >> runS (beginScopeS kernel) >> go p' ps++        -- modPathS commonly fails here because the path is unchanged, so throw away failures+        restore p = catchM (runS $ modPathS kernel (<> pathToSnocPath p) env)+                           (const (return ()))++    go h t++-- | Run a kernel function on the current SAST+runK :: (SAST -> CLM IO a) -> CLM IO a+runK f = gets cl_cursor >>= f++-- | Run a kernel function on the current SAST and update cl_cursor+runS :: (SAST -> CLM IO SAST) -> CLM IO ()+runS f = do+    sast <- runK f+    modify $ \st -> st { cl_cursor = sast }++interactive :: [External] -> [CommandLineOption] -> OM ()+interactive es os = OM . singleton $ Shell (externals ++ es) os++run :: RewriteH Core -> OM ()+run = OM . singleton . RR++query :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g a -> OM a+query = OM . singleton . Query++----------------------------- guards ------------------------------++guard :: (PhaseInfo -> Bool) -> OM () -> OM ()+guard p = OM . singleton . Guard p++at :: TranslateH Core LocalPathH -> OM a -> OM a+at tp = OM . singleton . Focus tp++phase :: Int -> OM () -> OM ()+phase n = guard ((n ==) . phaseNum)++after :: CorePass -> OM () -> OM ()+after cp = guard (\phaseInfo -> case phasesDone phaseInfo of+                            [] -> False+                            xs -> last xs == cp)++before :: CorePass -> OM () -> OM ()+before cp = guard (\phaseInfo -> case phasesLeft phaseInfo of+                            (x:_) | cp == x -> True+                            _               -> False)++allPhases :: OM () -> OM ()+allPhases = guard (const True)++firstPhase :: OM () -> OM ()+firstPhase = guard (null . phasesDone)++lastPhase :: OM () -> OM ()+lastPhase = guard (null . phasesLeft)++----------------------------- other ------------------------------++display :: OM ()+display = OM $ lift $ performQuery Display++setPretty :: PrettyH CoreTC -> OM ()+setPretty pp = OM $ modify $ \s -> s { cl_pretty = pp }++setPrettyOptions :: PrettyOptions -> OM ()+setPrettyOptions po = OM $ modify $ \s -> s { cl_pretty_opts = po }
+ src/HERMIT/Parser.y view
@@ -0,0 +1,195 @@+{+module HERMIT.Parser+    ( Script+    , parseScript+    , unparseScript+    , unparseExprH+    , ExprH(..)+    ) where++import Data.Char (isSpace)+import Data.List (intercalate)++import Control.Monad ((>=>))++import HERMIT.Syntax (isScriptInfixIdChar, isScriptIdFirstChar, isScriptIdChar)++}++%name parser+%tokentype { Token }+%error { parseError }+%monad { Either String } { >>= } { return }++%token+    '('     { ParenLeft }+    ')'     { ParenRight }+    '{'     { ScopeStart }+    '}'     { ScopeEnd }+    '['     { ListStart }+    ','     { ListDelim }+    ']'     { ListEnd }+    ';'     { StmtEnd }+    '\''    { Tick }+    core    { CoreString $$ }+    quoted  { Quote $$ }+    ident   { Ident $$ }+    infixop { InfixOp $$ }++%%++scoped : '{' scoped { CmdName "{" : $2 }+       | '}' scoped { CmdName "}" : $2 }+       | slist      { $1 }++slist : stmts       { $1 }+      | {- empty -} { [] }++-- | Be really liberal about where ';' can be!+--   Recall that newlines are lexed as ';'+stmts : ExprH            { [$1] }+      | ExprH '}' scoped { [$1, CmdName "}"] ++ $3 }+      | ExprH ';' scoped { $1 : $3 }+      | ';' scoped       { $2 }++-- | Top level expression term.+--   Infix operators bind less tightly than application.+ExprH : e2 infixop ExprH   { AppH (AppH (CmdName $2) $1) $3 }+      | e2                 { $1 }++-- | Expressions without infix operators in them.+e2   : e2 arg          { AppH $1 $2 }+     | arg             { $1 }++-- | Expressions that can be arguments in an application.+arg  : '\'' ident      { SrcName $2 }+     | '\'' infixop    { SrcName $2 }+     | '\'' quoted     { SrcName $2 }+     | quoted          { CmdName $1 }+     | core            { CoreH $1 }+     | '[' elist ']'   { ListH $2 }+     | '(' ExprH ')'   { $2 }+     | ident           { CmdName $1 }++elist : exprs       { $1 }+      | {- empty -} { [] }++exprs : ExprH           { [$1] }+      | ExprH ',' exprs { $1 : $3 }+{++parseError :: [Token] -> Either String a+parseError ts = Left $ "Parse error: " ++ show ts++-- | A simple expression language AST, for things parsed from 'String' or JSON structures.+data ExprH+    = SrcName String                -- ^ Variable names (refers to source code).+    | CmdName String                -- ^ Commands (to be looked up in 'HERMIT.Dictionary').+    | AppH ExprH ExprH              -- ^ Application.+    | CoreH String                  -- ^ Core Fragment+    | ListH [ExprH]                 -- ^ List of expressions+    deriving (Eq, Show)++data Token+    = ParenLeft+    | ParenRight+    | ScopeStart+    | ScopeEnd+    | ListStart+    | ListDelim+    | ListEnd+    | StmtEnd+    | Tick+    | CoreString String+    | Quote String+    | Ident String+    | InfixOp String+    deriving (Eq, Show)++lexError :: String -> Either String a+lexError msg = Left ("Lexer error: " ++ msg)++lexer :: String -> Either String [Token]+lexer []           = Right []+lexer ('\n':cs)    = fmap (StmtEnd:)    $ lexer cs+lexer (';' :cs)    = fmap (StmtEnd:)    $ lexer cs+lexer ('(' :cs)    = fmap (ParenLeft:)  $ lexer cs+lexer (')' :cs)    = fmap (ParenRight:) $ lexer cs+lexer ('{' :cs)    = fmap (ScopeStart:) $ lexer cs+lexer ('}' :cs)    = fmap (ScopeEnd:)   $ lexer cs+lexer ('\'':cs)    = fmap (Tick:)       $ lexer cs+lexer ('\"':cs)    = do (str,cs') <- lexString cs+                        fmap (Quote str:) $ lexer cs'+lexer ('[':'|':cs) = do (str,cs') <- lexCore cs+                        fmap (CoreString str:) $ lexer cs'+lexer ('-':'-':cs) = let (_,s') = span (/= '\n') cs in lexer s'+lexer ('[' :cs)    = fmap (ListStart:)  $ lexer cs+lexer (',' :cs)    = fmap (ListDelim:)  $ lexer cs+lexer (']' :cs)    = fmap (ListEnd:)    $ lexer cs+lexer s@(c:cs)     | isSpace             c = lexer cs+                   | isScriptIdFirstChar c = let (i,s') = span isScriptIdChar s+                                              in fmap (Ident i:) $ lexer s'+                   | isScriptInfixIdChar c = let (op,s') = span isScriptInfixIdChar s+                                              in fmap (InfixOp op:) $ lexer s'+lexer s            = lexError $ "no match on " ++ s++lexString :: String -> Either String (String,String)+lexString ('\"':cs)      = Right ([],cs)+lexString ('\\':'\"':cs) = do (c',r) <- lexString cs+                              return ('"':c',r)+lexString (c:cs)         = do (c',r) <- lexString cs+                              return (c:c',r)+lexString []             = lexError "no matching quote"++lexCore :: String -> Either String (String,String)+lexCore ('|':']':rest) = Right ([],rest)+lexCore (c:cs)         = do (c',r) <- lexCore cs+                            return (c:c',r)+lexCore []             = lexError "no closing |]"++---------------------------------------------++-- | Use ghci Parser.hs to run this test function.+test = do+    ln <- getLine+    case ln of+        "quit" -> return ()+        _      -> do print $ lexer ln+                     print $ parseScript ln+                     test++type Script = [ExprH]++parseScript :: String -> Either String Script+parseScript = lexer >=> parser++---------------------------------------------++unparseScript :: Script -> String+unparseScript = intercalate " ; " . map unparseExprH++unparseExprH :: ExprH -> String+unparseExprH (SrcName nm)+    | nm /= "" && (all isScriptInfixIdChar nm || isScriptIdFirstChar (head nm) && all isScriptIdChar (tail nm)) = "'" ++ nm+    | otherwise = "'\"" ++ concatMap escape nm ++ "\""+        where escape '\"' = "\\\""+              escape c    = [c]+unparseExprH (CmdName nm)+    | nm == "{"             = "{ "+    | nm == "}"             = " }"+    | all isScriptIdChar nm = nm+    | otherwise             = show nm     -- with quotes+unparseExprH (AppH (AppH (CmdName nm) e1) e2)+    | all isScriptInfixIdChar nm+    = unparseAtom e1 ++ " " ++ nm ++ " " ++ unparseAtom e2+unparseExprH (AppH e1 e2) = unparseExprH e1 ++ " " ++ unparseAtom e2+unparseExprH (CoreH s)    = "[|" ++ s ++ "|]"+unparseExprH (ListH es)   = "[" ++ intercalate "," (map unparseExprH es) ++ "]"++unparseAtom :: ExprH -> String+unparseAtom e@(AppH {}) = "(" ++ unparseExprH e ++ ")"+unparseAtom e           = unparseExprH e++---------------------------------------------++}
+ src/HERMIT/ParserCore.y view
@@ -0,0 +1,186 @@+{+{-# LANGUAGE CPP #-}+ module HERMIT.ParserCore (parseCore, parseCoreExprT, parse2beforeBiR, parse3beforeBiR) where++import Control.Arrow+import Control.Monad.Reader+import Data.Char (isSpace, isDigit)++import HERMIT.Context+import HERMIT.External+import HERMIT.GHC+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Syntax (isCoreInfixIdChar, isCoreIdFirstChar, isCoreIdChar)++import HERMIT.Dictionary.Common++import Language.KURE.MonadCatch (prefixFailMsg)++import Language.Haskell.TH as TH+}++%name parser+%tokentype { Token }+%error { parseError }+%monad { CoreParseM } { >>= } { return }++%token+    '%forall'  { Tforall }+    '%rec'     { Trec }+    '%let'     { Tlet }+    '%in'      { Tin }+    '%case'    { Tcase }+    '%of'      { Tof }+    '%cast'    { Tcast }+    '%note'    { Tnote }+    '%external'    { Texternal }+    '%local'   { Tlocal }+    '%_'       { Twild }+    '('        { Toparen }+    ')'        { Tcparen }+    '{'        { Tobrace }+    '}'        { Tcbrace }+    '#'        { Thash}+    '='        { Teq }+    ':'        { Tcolon }+    '::'       { Tcoloncolon }+    ':=:'      { Tcoloneqcolon }+    '*'        { Tstar }+    '->'       { Tarrow }+    '\\'       { Tlambda}+    '@'        { Tat }+    '.'        { Tdot }+    '?'        { Tquestion}+    ';'            { Tsemicolon }+    NAME       { Tname $$ }+    CNAME      { Tcname $$ }+    INTEGER    { Tinteger $$ }+    RATIONAL   { Trational $$ }+    STRING     { Tstring $$ }+    CHAR       { Tchar $$ }++%%++-- | Top level expression term.+expr : app             { $1 }++app : app arg          { App $1 $2 }+    | arg              { $1 }++arg : '(' expr ')'     { $2 }+    | '(' ')'          {% lookupName "()" Var }+    | var              { $1 }+    | intlit           { $1 }+    | strlit           { $1 }++intlit : INTEGER       {% mkIntExpr' $1 } -- mkIntLit makes a primitive Int#++strlit : STRING        {% lift $ mkStringExpr $1 }++var : NAME             {% lookupName $1 varToCoreExpr }+{++mkIntExpr' :: Integer -> CoreParseM CoreExpr+#if __GLASGOW_HASKELL__ > 706+mkIntExpr' i = do+    dflags <- lift getDynFlags+    return $ mkIntExpr dflags i+#else+mkIntExpr' i = return $ mkIntExpr i+#endif++lookupName :: String -> (Id -> CoreExpr) -> CoreParseM CoreExpr+lookupName nm k = do+    c <- ask+    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId (TH.mkName nm) c+    return (k v)++type CoreParseM a = ReaderT HermitC HermitM a++parseError :: Monad m => [Token] -> m a+parseError ts = fail $ "core parse error: " ++ show ts++data Token+    = Tforall+    | Trec+    | Tlet+    | Tin+    | Tcase+    | Tof+    | Tcast+    | Tnote+    | Texternal+    | Tlocal+    | Twild --+    | Toparen --+    | Tcparen --+    | Tobrace+    | Tcbrace+    | Thash+    | Teq+    | Tcolon --+    | Tcoloncolon --+    | Tcoloneqcolon+    | Tstar+    | Tarrow+    | Tlambda --+    | Tat+    | Tdot+    | Tquestion+    | Tsemicolon+    | Tname String+    | Tcname String+    | Tinteger Integer+    | Trational Float+    | Tstring String+    | Tchar Char+    deriving (Eq, Show)++lexer :: String -> Either String [Token]+lexer []           = Right []+lexer ('_' :cs)    = fmap (Twild:)       $ lexer cs+lexer ('(' :cs)    = fmap (Toparen:)     $ lexer cs+lexer (')' :cs)    = fmap (Tcparen:)     $ lexer cs+lexer (':':':':cs) = fmap (Tcoloncolon:) $ lexer cs+-- lexer (':' :cs)    = fmap (Tcolon:)      $ lexer cs+lexer ('\\':cs)    = fmap (Tlambda:)     $ lexer cs+lexer ('-':'>':cs) = fmap (Tarrow:)      $ lexer cs+lexer ('\"':cs)    = let (str,rest) = span (/='\"') cs+                     in case rest of+                           ('\"':cs') -> fmap (Tstring str:) $ lexer cs'+                           _          -> Left "lexer: no matching quote"+lexer s@(c:cs) | isSpace           c = lexer cs+               | isDigit           c = let (i,s') = span isDigit s+                                         in fmap (Tinteger (read i):) $ lexer s'+               | isCoreIdFirstChar c = let (i,s') = span isCoreIdChar s+                                         in fmap (Tname i:) $ lexer s'+               | isCoreInfixIdChar c = let (op,s') = span isCoreInfixIdChar s+                                         in fmap (Tname op:) $ lexer s'+lexer s            = Left $ "lexer: no match on " ++ s++---------------------------------------------++parseCore :: CoreString -> HermitC -> HermitM CoreExpr+parseCore (CoreString s) c =+    case lexer s of+        Left msg -> fail msg+        Right tokens -> runReaderT (parser tokens) c++---------------------------------------------++-- These three should probably go somewhere else.++-- | Parse a 'CoreString' to a 'CoreExpr', using the current context.+parseCoreExprT :: CoreString -> TranslateH a CoreExpr+parseCoreExprT = contextonlyT . parseCore++parse2beforeBiR :: (CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> BiRewriteH a+parse2beforeBiR f s1 s2 = beforeBiR (parseCoreExprT s1 &&& parseCoreExprT s2) (uncurry f)++parse3beforeBiR :: (CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> CoreString -> BiRewriteH a+parse3beforeBiR f s1 s2 s3 = beforeBiR ((parseCoreExprT s1 &&& parseCoreExprT s2) &&& parseCoreExprT s3) ((uncurry.uncurry) f)++---------------------------------------------++}
+ src/HERMIT/Plugin.hs view
@@ -0,0 +1,128 @@+module HERMIT.Plugin+    ( -- * The HERMIT Plugin+      HermitPass+    , hermitPlugin+    , CorePass(..)+    , getCorePass+    , ghcPasses+    , PhaseInfo(..)+    )  where++import Data.List+import System.IO++import HERMIT.GHC++-- | Given a list of 'CommandLineOption's, produce the 'ModGuts' to 'ModGuts' function required to build a plugin.+type HermitPass = PhaseInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts++-- | Build a hermit plugin. This mainly handles the per-module options.+hermitPlugin :: HermitPass -> Plugin+hermitPlugin hp = defaultPlugin { installCoreToDos = install }+    where+        install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]+        install opts todos = do+            reinitializeGlobals++            -- This is a bit of a hack; otherwise we lose what we've not seen+            liftIO $ hSetBuffering stdout NoBuffering++            let passes = map getCorePass todos+                allPasses = foldr (\ (n,p,seen,notyet) r -> mkPass n seen notyet : p : r)+                                  [mkPass (length todos) passes []]+                                  (zip4 [0..] todos (inits passes) (tails passes))+                mkPass n ps ps' = CoreDoPluginPass ("HERMIT" ++ show n) $ modFilter hp (PhaseInfo n ps ps') opts++            return allPasses++-- | Determine whether to act on this module, choose plugin pass.+-- NB: we have the ability to stick module info in the phase info here+modFilter :: HermitPass -> HermitPass+modFilter hp pInfo opts guts+    | null modOpts && notNull opts = return guts -- don't process this module+    | otherwise                    = hp pInfo (h_opts ++ filter notNull modOpts) guts+    where modOpts = filterOpts m_opts guts+          (m_opts, h_opts) = partition (isInfixOf ":") opts++-- | Filter options to those pertaining to this module, stripping module prefix.+filterOpts :: [CommandLineOption] -> ModGuts -> [CommandLineOption]+filterOpts opts guts = [ drop len nm | nm <- opts, modName `isPrefixOf` nm ]+    where modName = moduleNameString $ moduleName $ mg_module guts+          len = length modName + 1 -- for the colon++data CorePass = FloatInwards+              | LiberateCase+              | PrintCore+              | StaticArgs+              | Strictness+              | WorkerWrapper+              | Specialising+              | SpecConstr+              | CSE+              | Vectorisation+              | Desugar+              | DesugarOpt+              | Tidy+              | Prep+              | Simplify+              | FloatOutwards+              | RuleCheck+              | Passes -- these should be flattened out in practice+              | PluginPass String+              | NoOp+              | Unknown+    deriving (Read, Show, Eq)++ghcPasses :: [(CorePass, CoreToDo)]+ghcPasses = [ (FloatInwards , CoreDoFloatInwards)+            , (LiberateCase , CoreLiberateCase)+            , (PrintCore    , CoreDoPrintCore)+            , (StaticArgs   , CoreDoStaticArgs)+            , (Strictness   , CoreDoStrictness)+            , (WorkerWrapper, CoreDoWorkerWrapper)+            , (Specialising , CoreDoSpecialising)+            , (SpecConstr   , CoreDoSpecConstr)+            , (CSE          , CoreCSE)+            , (Vectorisation, CoreDoVectorisation)+            , (Desugar      , CoreDesugar)    -- Right after desugaring, no simple optimisation yet!+            , (DesugarOpt   , CoreDesugarOpt) -- CoreDesugarXXX: Not strictly a core-to-core pass, but produces+            , (Tidy         , CoreTidy)+            , (Prep         , CorePrep)+            , (NoOp         , CoreDoNothing)+            ]++-- The following are not allowed yet because they required options.+-- CoreDoSimplify {- The core-to-core simplifier. -} Int {- Max iterations -} SimplifierMode+-- CoreDoFloatOutwards FloatOutSwitches+-- CoreDoRuleCheck CompilerPhase String   -- Check for non-application of rules matching this string+-- CoreDoPasses [CoreToDo]                -- lists of these things++getCorePass :: CoreToDo -> CorePass+getCorePass CoreDoFloatInwards  = FloatInwards+getCorePass CoreLiberateCase    = LiberateCase+getCorePass CoreDoPrintCore     = PrintCore+getCorePass CoreDoStaticArgs    = StaticArgs+getCorePass CoreDoStrictness    = Strictness+getCorePass CoreDoWorkerWrapper = WorkerWrapper+getCorePass CoreDoSpecialising  = Specialising+getCorePass CoreDoSpecConstr    = SpecConstr+getCorePass CoreCSE             = CSE+getCorePass CoreDoVectorisation = Vectorisation+getCorePass CoreDesugar         = Desugar+getCorePass CoreDesugarOpt      = DesugarOpt+getCorePass CoreTidy            = Tidy+getCorePass CorePrep            = Prep+getCorePass (CoreDoSimplify {}) = Simplify+getCorePass (CoreDoFloatOutwards {}) = FloatOutwards+getCorePass (CoreDoRuleCheck {}) = RuleCheck+getCorePass (CoreDoPasses {})   = Passes -- these should be flattened out in practice+getCorePass (CoreDoPluginPass nm _) = PluginPass nm+getCorePass CoreDoNothing       = NoOp+-- getCorePass _                   = Unknown++data PhaseInfo =+    PhaseInfo { phaseNum :: Int+              , phasesDone :: [CorePass]+              , phasesLeft :: [CorePass]+              }+    deriving (Read, Show, Eq)
+ src/HERMIT/PrettyPrinter/AST.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE CPP #-}++-- | Output the raw Expr constructors. Helpful for writing pattern matching rewrites.+module HERMIT.PrettyPrinter.AST+  ( -- * HERMIT's AST Pretty-Printer for GHC Core+    ppCoreTC+  , ppModGuts+  , ppCoreProg+  , ppCoreBind+  , ppCoreExpr+  , ppCoreAlt+  , ppKindOrType+  , ppCoercion+  )+where++import Control.Arrow hiding ((<+>))++import Data.Char (isSpace)++import HERMIT.GHC hiding (($$), (<+>), ($+$), cat, nest, parens, text, empty)+import HERMIT.Kure+import HERMIT.Core++import HERMIT.Dictionary (dynFlagsT)++import HERMIT.PrettyPrinter.Common++import Text.PrettyPrint.MarkedHughesPJ as PP++---------------------------------------------------------------------------++coText :: String -> DocH+coText = coercionColor . text++tyText :: String -> DocH+tyText = typeColor . text++---------------------------------------------------------------------------++-- | Pretty print a fragment of GHC Core using HERMIT's \"AST\" pretty printer.+--   This displays the tree of constructors using nested indentation.+ppCoreTC :: PrettyH CoreTC+ppCoreTC =+          promoteExprT     ppCoreExpr+       <+ promoteProgT     ppCoreProg+       <+ promoteBindT     ppCoreBind+       <+ promoteDefT      ppCoreDef+       <+ promoteModGutsT  ppModGuts+       <+ promoteAltT      ppCoreAlt+       <+ promoteTypeT     ppKindOrType+       <+ promoteCoercionT ppCoercion++-- Use for any GHC structure, the 'showSDoc' prefix is to remind us+-- that we are eliding infomation here.+ppSDoc :: Outputable a => PrettyH a+ppSDoc =  do dynFlags   <- dynFlagsT+             hideNotes  <- (po_notes . prettyC_options) ^<< contextT+             arr (toDoc . (if hideNotes then id else ("showSDoc: " ++)) . showPpr dynFlags)+    where toDoc s | any isSpace s = parens (text s)+                  | otherwise     = text s++ppModGuts :: PrettyH ModGuts+ppModGuts =  mg_module ^>> ppSDoc++ppCoreProg :: PrettyH CoreProg+ppCoreProg = progConsT ppCoreBind ppCoreProg ($+$) <+ progNilT empty++ppCoreExpr :: PrettyH CoreExpr+ppCoreExpr = varT (ppVar >>^ \ i -> text "Var" <+> i)+          <+ litT (ppSDoc >>^ \ x -> text "Lit" <+> x)+          <+ appT ppCoreExpr ppCoreExpr (\ a b -> text "App" $$ nest 2 (cat [parens a, parens b]))+          <+ lamT ppVar ppCoreExpr (\ v e -> text "Lam" <+> v $$ nest 2 (parens e))+          <+ letT ppCoreBind ppCoreExpr (\ b e -> text "Let" $$ nest 2 (cat [parens b, parens e]))+          <+ caseT ppCoreExpr ppVar ppKindOrType (const ppCoreAlt) (\s w ty alts ->+                    text "Case" $$ nest 2 (parens s) $$ nest 2 w $$ nest 2 (parens ty) $$ nest 2 (vlist alts))+          <+ castT ppCoreExpr ppCoercion (\ e co -> text "Cast" $$ nest 2 (cat [parens e, parens co]))+          <+ tickT ppSDoc ppCoreExpr (\ tk e  -> text "Tick" $$ nest 2 (tk <+> parens e))+          <+ typeT (ppKindOrType >>^ \ ty -> text "Type" $$ nest 2 (parens ty))+          <+ coercionT (ppCoercion >>^ \ co -> text "Coercion" $$ nest 2 (parens co))++ppCoreBind :: PrettyH CoreBind+ppCoreBind = nonRecT ppVar ppCoreExpr (\ v e -> text "NonRec" <+> v $$ nest 2 (parens e))+          <+ recT (const ppCoreDef) (\ bnds -> text "Rec" $$ nest 2 (vlist bnds))++ppCoreAlt :: PrettyH CoreAlt+ppCoreAlt = altT ppSDoc (\ _ -> ppVar) ppCoreExpr $ \ con vs e -> text "Alt" <+> con <+> hlist vs $$ nest 2 (parens e)++ppCoreDef :: PrettyH CoreDef+ppCoreDef = defT ppVar ppCoreExpr (\ i e -> text "Def" <+> i $$ nest 2 (parens e))++ppKindOrType :: PrettyH Type+ppKindOrType =+          tyVarT (ppVar >>^ \ v -> tyText "TyVarTy" <+> v)+       <+ litTyT (ppSDoc >>^ \ l -> tyText "LitTy" <+> l)+       <+ appTyT ppKindOrType ppKindOrType (\ ty1 ty2 -> tyText "AppTy" $$ nest 2 (cat [parens ty1, parens ty2]))+       <+ funTyT ppKindOrType ppKindOrType (\ ty1 ty2 -> tyText "FunTy" $$ nest 2 (cat [parens ty1, parens ty2]))+       <+ forAllTyT ppVar ppKindOrType (\ v ty -> tyText "ForAllTy" <+> v $$ nest 2 (parens ty))+       <+ tyConAppT ppSDoc (const ppKindOrType) (\ con tys -> tyText "TyConApp" <+> con $$ nest 2 (vlist $ map parens tys))++ppCoercion :: PrettyH Coercion+ppCoercion =  coVarCoT (ppVar >>^ \ v -> coText "CoVarCo" <+> v)+           <+ symCoT (ppCoercion >>^ \ co -> coText "SymCo" $$ nest 2 (parens co))+           <+ appCoT ppCoercion ppCoercion (\ co1 co2 -> coText "AppCo" $$ nest 2 (cat [parens co1, parens co2]))+           <+ forAllCoT ppVar ppCoercion (\ v co -> coText "ForAllCo" <+> v $$ nest 2 (parens co))+           <+ transCoT ppCoercion ppCoercion (\ co1 co2 -> coText "TransCo" $$ nest 2 (cat [parens co1, parens co2]))+           <+ nthCoT (arr $ coText . show) ppCoercion (\ n co -> coText "NthCo" <+> n $$ parens co)+           <+ instCoT ppCoercion ppKindOrType (\ co ty -> coText "InstCo" $$ nest 2 (cat [parens co, parens ty]))+#if __GLASGOW_HASKELL__ > 706+-- TODO: Figure out how to properly pp new branched Axioms and Left/Right Coercions+           <+ reflT ppKindOrType (\ r ty -> coText "Refl" <+> coText (showRole r) $$ nest 2 (parens ty))+           <+ axiomInstCoT ppSDoc ppSDoc (const ppCoercion) (\ ax idx coes -> coText "AxiomInstCo" <+> ax <+> idx $$ nest 2 (vlist $ map parens coes))+           <+ lrCoT ppSDoc ppCoercion (\ lr co -> coText "LRCo" <+> lr $$ nest 2 (parens co))+           <+ tyConAppCoT ppSDoc (const ppCoercion) (\ r con coes -> coText "TyConAppCo" <+> coText (showRole r) <+> con $$ nest 2 (vlist $ map parens coes))+           -- TODO: add UnivCo and SubCo+#else+           <+ reflT (ppKindOrType >>^ \ ty -> coText "Refl" $$ nest 2 (parens ty))+           <+ tyConAppCoT ppSDoc (const ppCoercion) (\ con coes -> coText "TyConAppCo" <+> con $$ nest 2 (vlist $ map parens coes))+           <+ unsafeCoT ppKindOrType ppKindOrType (\ ty1 ty2 -> coText "UnsafeCo" $$ nest 2 (cat [parens ty1, parens ty2]))+           <+ axiomInstCoT ppSDoc (const ppCoercion) (\ ax coes -> coText "AxiomInstCo" <+> ax $$ nest 2 (vlist $ map parens coes))+#endif++ppVar :: PrettyH Var+ppVar = readerT $ \ v -> ppSDoc >>^ modCol v+  where+    modCol v | isTyVar v  = typeColor+             | isCoVar v  = coercionColor+             | otherwise  = idColor++---------------------------------------------------------------------------
+ src/HERMIT/PrettyPrinter/Clean.hs view
@@ -0,0 +1,444 @@+{-# LANGUAGE CPP, LambdaCase, MultiWayIf #-}++module HERMIT.PrettyPrinter.Clean+  ( -- * HERMIT's Clean Pretty-Printer for GHC Core+    ppCoreTC+  , ppModGuts+  , ppCoreProg+  , ppCoreBind+  , ppCoreExpr+  , ppCoreAlt+  , ppKindOrType+  , ppCoercion+  )+where++import Control.Arrow hiding ((<+>))+import Control.Applicative ((<$>))++import Data.Char (isSpace)++import HERMIT.Context+import HERMIT.Core+import HERMIT.GHC hiding ((<+>), (<>), ($$), ($+$), sep, hsep, empty, nest, vcat, char, text, keyword, hang)+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Syntax++import HERMIT.Dictionary (dynFlagsT)++import HERMIT.PrettyPrinter.Common++import Pair++import Text.PrettyPrint.MarkedHughesPJ as PP++------------------------------------------------------------------------------------------------++data RetExpr+        = RetLam AbsolutePathH [DocH] AbsolutePathH DocH+        | RetLet AbsolutePathH [DocH] AbsolutePathH DocH+        | RetApp DocH [(AbsolutePathH,RetExpr)]+        | RetForAll AbsolutePathH [DocH] AbsolutePathH DocH+        | RetArrowType DocH [(AbsolutePathH,DocH)] -- f -> (a -> (b -> c))  The path is for each arrow, starting from the left.+        | RetExpr DocH+        | RetAtom DocH         -- parens not needed+        | RetEmpty++retApp :: AbsolutePathH -> Crumb -> Crumb -> RetExpr -> RetExpr -> RetExpr+retApp _ _   _   f              RetEmpty = f+retApp _ _   _   RetEmpty       e        = e+retApp p _   cr2 (RetApp f pes) e        = RetApp f (pes ++ [(p @@ cr2, e)])+retApp p cr1 cr2 f              e        = RetApp (normalParens (p @@ cr1) f) [(p @@ cr2, e)]++-- empties should not arise+retApps :: AbsolutePathH -> (Int -> Crumb) -> DocH -> [RetExpr] -> RetExpr+retApps p crumb f es = RetApp f [ ((p @@ crumb n),e) | (e,n) <- zip es [1..]]++retLam :: AbsolutePathH -> DocH -> RetExpr -> RetExpr+retLam p v = if isEmpty v+              then id+              else \case+                      RetLam _ vs pb e -> RetLam p (v : vs) pb e+                      e                -> RetLam p [v] (p @@ Lam_Body) (normalExpr e)++retLet :: AbsolutePathH -> DocH -> RetExpr -> RetExpr+retLet p bnd = if isEmpty bnd+                then id+                else \case+                        RetLet _ bnds pb body -> RetLet p (bnd : bnds) pb body+                        body                  -> RetLet p [bnd] (p @@ Let_Body) (normalExpr body)++retForAll :: AbsolutePathH -> Crumb -> DocH -> RetExpr -> RetExpr+retForAll p cr v = if isEmpty v+                    then id+                    else \case+                            RetForAll _ vs pb ty  -> RetForAll p (v : vs) pb ty+                            ty                    -> RetForAll p [v] (p @@ cr) (normalExpr ty)++-- This is very hacky.  There must be a better way of handling arrow types.+retArrowType :: AbsolutePathH -> Crumb -> Crumb -> RetExpr -> RetExpr -> RetExpr+retArrowType p cr1 cr2 ty1 = \case+                                RetArrowType ty2 ptys  -> RetArrowType (normalParensExceptApp (p @@ cr1) ty1) ((p,ty2) : ptys)+                                ty2                    -> RetArrowType (normalParensExceptApp (p @@ cr1) ty1) [(p , normalParensExceptApp (p @@ cr2) ty2)]++------------------------------------------------------------------------------------------------++isAtom :: RetExpr -> Bool+isAtom (RetAtom _) = True+isAtom _           = False++------------------------------------------------------------------------------------------------++normalExpr :: RetExpr -> DocH+normalExpr  RetEmpty           = empty+normalExpr (RetAtom e)         = e+normalExpr (RetExpr e)         = e+normalExpr (RetLam p vs pb e)  = hang (specialSymbol p LambdaSymbol <+> hsep vs <+> specialSymbol pb RightArrowSymbol) 2 e+normalExpr (RetLet p vs pb e)  = sep [ keyword p "let" <+> vcat vs, keyword pb "in" <+> e ]+normalExpr (RetApp f pes)      = let (pAtoms,pExprs) = span (isAtom.snd) pes+                                  in sep [ hsep (f : map (normalExpr.snd) pAtoms)+                                         , nest 2 (sep $ map (uncurry normalParens) pExprs) ]+normalExpr (RetForAll p vs pb ty) = specialSymbol p ForallSymbol <+> hsep vs <+> symbol pb '.' <+> ty+normalExpr (RetArrowType ty ptys) = foldl (\ ty1 (p,ty2) -> ty1 <+> typeArrow p <+> ty2) ty ptys++------------------------------------------------------------------------------------------------++cleanParens :: AbsolutePathH -> DocH -> DocH+cleanParens p e = symbol p '(' <> e <> symbol p ')'++normalParens :: AbsolutePathH -> RetExpr -> DocH+normalParens p = \case+                    RetEmpty    -> empty+                    RetAtom e   -> e+                    RetApp f [] -> f+                    e           -> cleanParens p (normalExpr e)++normalParensExceptApp :: AbsolutePathH -> RetExpr -> DocH+normalParensExceptApp p = \case+                             e@RetApp{} -> normalExpr e+                             e          -> normalParens p e++------------------------------------------------------------------------------------------------++parenExpr :: PrettyH RetExpr+parenExpr = do p <- absPathT+               arr (normalParens p)++parenExprExceptApp :: PrettyH RetExpr+parenExprExceptApp = do p <- absPathT+                        arr (normalParensExceptApp p)++------------------------------------------------------------------------------------------------++specialSymbol :: AbsolutePathH -> SpecialSymbol -> DocH+specialSymbol p = attrP p . markColor SyntaxColor . specialFont . char . renderSpecial++symbol :: AbsolutePathH -> Char -> DocH+symbol p = attrP p . markColor SyntaxColor . char++keyword :: AbsolutePathH -> String -> DocH+keyword p = attrP p . markColor KeywordColor . text++idText :: AbsolutePathH -> String -> DocH+idText p = attrP p . text+++coText :: AbsolutePathH -> String -> DocH+coText p = attrP p . coercionColor . text++coChar :: AbsolutePathH -> Char -> DocH+coChar p = attrP p . coercionColor . char++coSymbol :: AbsolutePathH -> SpecialSymbol -> DocH+coSymbol p = attrP p . coercionColor . specialFont . char . renderSpecial++castSymbol :: AbsolutePathH -> DocH+castSymbol p = coSymbol p CastSymbol++coercionSymbol :: AbsolutePathH -> DocH+coercionSymbol p = coSymbol p CoercionSymbol++coercionBindSymbol :: AbsolutePathH -> DocH+coercionBindSymbol p = coSymbol p CoercionBindSymbol++coKeyword :: AbsolutePathH -> String -> DocH+coKeyword = coText -- An alternative would be keyword.+++tyChar :: AbsolutePathH -> Char -> DocH+tyChar p = attrP p . typeColor . char++tyText :: AbsolutePathH -> String -> DocH+tyText p = attrP p . typeColor . text++tySymbol :: AbsolutePathH -> SpecialSymbol -> DocH+tySymbol p = attrP p . typeColor . specialFont . char . renderSpecial++typeSymbol :: PrettyH a+typeSymbol = do p <- absPathT+                return (tySymbol p TypeSymbol)++typeBindSymbol :: AbsolutePathH -> DocH+typeBindSymbol p = tySymbol p TypeBindSymbol++typeOfSymbol :: AbsolutePathH -> DocH+typeOfSymbol p = tySymbol p TypeOfSymbol++typeArrow :: AbsolutePathH -> DocH+typeArrow p = tySymbol p RightArrowSymbol++------------------------------------------------------------------------------------------------++-- | Pretty print a fragment of GHC Core using HERMIT's \"Clean\" pretty printer.+ppCoreTC :: PrettyH CoreTC+ppCoreTC =+          promoteExprT     ppCoreExpr+       <+ promoteProgT     ppCoreProg+       <+ promoteBindT     ppCoreBind+       <+ promoteDefT      ppCoreDef+       <+ promoteModGutsT  ppModGuts+       <+ promoteAltT      ppCoreAlt+       <+ promoteTypeT     ppKindOrType+       <+ promoteCoercionT ppCoercion+++-- Use for any GHC structure+ppSDoc :: Outputable a => PrettyH a+ppSDoc = do dynFlags <- dynFlagsT+            p        <- absPathT+            doc      <- arr (showPpr dynFlags)+            if any isSpace doc+             then return (cleanParens p (idText p doc))+             else return (idText p doc)++ppVar :: PrettyH Var+ppVar = readerT $ \ v -> varName ^>> ppName (varColor v)++varColor :: Var -> SyntaxForColor+varColor var | isTyVar var = TypeColor+             | isCoVar var = CoercionColor+             | otherwise   = IdColor++ppName :: SyntaxForColor -> PrettyH Name+ppName color = do p    <- absPathT+                  name <- arr uqName+                  let doc = attrP p $ markColor color $ text name+                               -- TODO: is "isScriptInfixId" the right predicate to use here?+                  if all isScriptInfixIdChar name+                     then return (cleanParens p doc)+                     else return doc++ppLitTy :: PrettyH TyLit+ppLitTy = do p <- absPathT+             arr $ \ lit -> tyText p $ case lit of+                                         NumTyLit i  -> show i+                                         StrTyLit fs -> show fs++ppTyCon :: PrettyH TyCon+ppTyCon = getName ^>> ppName TypeColor++ppTyConCo :: PrettyH TyCon+ppTyConCo = getName ^>> ppName CoercionColor++-- binders are vars that is bound by lambda or case, etc.+-- depending on the mode, they might not be displayed+ppBinderMode :: PrettyH Var+ppBinderMode = do p    <- absPathT+                  v    <- idR+                  opts <- prettyC_options ^<< contextT+                  if+                     | isTyVar v -> case po_exprTypes opts of+                                                           Omit     -> return empty+                                                           Abstract -> return (typeBindSymbol p)+                                                           _        -> ppVar+                     | isCoVar v -> case po_coercions opts of+                                                           Omit     -> return empty+                                                           Abstract -> return (coercionBindSymbol p)+                                                           Show     -> ppVar+                                                           Kind     -> do pCoKind <- ppCoKind <<^ CoVarCo+                                                                          return $ cleanParens p (coercionBindSymbol p <+> typeOfSymbol p <+> pCoKind)+                                                          -- TODO: refactor this to be more systematic.  It should be possible to request type sigs for all type bindings.+                     | otherwise       -> ppVar++ppModGuts :: PrettyH ModGuts+ppModGuts = do p    <- absPathT+               name <- ppSDoc <<^ mg_module+               modGutsT ppProg (\ _ prog -> hang (keyword p "module" <+> name <+> keyword p "where") 2 prog)+    where+      ppProg :: PrettyH CoreProg+      ppProg = progConsT ppBind ppProg ($+$) <+ progNilT empty++      ppBind :: PrettyH CoreBind+      ppBind =    (absPathT >>= \ p -> nonRecT ppVar (exprKindOrType ^>> ppKindOrType) (\ v ty -> v <+> typeOfSymbol p <+> ty))+               <+ recT (\ _ -> absPathT &&& defT ppVar (exprKindOrType ^>> ppKindOrType) (,)) (\ pvtys -> vcat [ v <+> typeOfSymbol p <+> ty | (p,(v,ty)) <- pvtys ])++ppCoreProg :: PrettyH CoreProg+ppCoreProg = progConsT ppCoreBind ppCoreProg ($+$) <+ progNilT empty++ppCoreBind :: PrettyH CoreBind+ppCoreBind =   (nonRecT idR (ppCoreExprR &&& ppTypeSig) (,) >>> ppDef NonRec_RHS)+            <+ (do p <- absPathT+                   recT (const ppCoreDef) (\ bnds -> keyword p "rec" <+> vcat bnds)+               )+++ppCoreAlt :: PrettyH CoreAlt+ppCoreAlt = do p <- absPathT+               altT (do p' <- absPathT+                        readerT $ \case+                                      DataAlt dcon -> return (getName dcon) >>> ppName IdColor+                                      LitAlt lit   -> return lit >>> ppSDoc+                                      DEFAULT      -> return (symbol p' '_')+                    )+                    (\ _ -> ppBinderMode)+                    ppCoreExpr+                    (\ con vs e -> hang (con <+> hsep vs <+> specialSymbol p RightArrowSymbol) 2 e)++ppCoreDef :: PrettyH CoreDef+ppCoreDef = defT idR (ppCoreExprR &&& ppTypeSig) (,) >>> ppDef Def_RHS++ppDef :: Crumb -> PrettyH (Var,(RetExpr,DocH))+ppDef cr = do p          <- absPathT+              (v,(e,ty)) <- idR+              opts       <- prettyC_options ^<< contextT+              let eq = symbol p '='+              case po_coercions opts of+                Omit | isCoVar v  -> return empty+                Kind | isCoVar v  -> return $ case po_exprTypes opts of+                                                    Show -> (coercionBindSymbol p <+> typeOfSymbol p <+> ty) $+$ (coercionBindSymbol p <+> eq <+> coercionSymbol (p @@ cr))+                                                    _    -> coercionBindSymbol p <+> eq <+> normalExpr e+                _                     -> do pv  <- ppBinderMode <<< return v+                                            let pre  = pv <+> eq+                                                body = case e of -- This is an ugly hack+                                                         RetLam p' vs pb e0 -> hang (pre <+> specialSymbol p' LambdaSymbol <+> hsep vs <+> specialSymbol pb RightArrowSymbol) 2 e0+                                                         _                  -> hang pre 2 (normalExpr e)+                                            return $ case po_exprTypes opts of+                                                       Omit | isTyVar v -> empty+                                                       Show                 -> (pv <+> typeOfSymbol p <+> ty) $+$ body+                                                       _                    -> body+++ppCoreExpr :: PrettyH CoreExpr+ppCoreExpr = ppCoreExprR >>^ normalExpr++ppCoreExprR :: Translate PrettyC HermitM CoreExpr RetExpr+ppCoreExprR = absPathT >>= ppCoreExprPR+  where+    ppCoreExprPR :: AbsolutePathH -> Translate PrettyC HermitM CoreExpr RetExpr+    ppCoreExprPR p =+              lamT ppBinderMode ppCoreExprR (retLam p)+           <+ letT ppCoreBind ppCoreExprR (retLet p)+           <+ appT ppCoreExprR ppCoreExprR (retApp p App_Fun App_Arg)+           <+ caseT ppCoreExpr ppVar (ppTypeModeR >>> parenExpr) (const ppCoreAlt) (\ s w ty alts -> RetExpr ((keyword p "case" <+> s <+> keyword p "of" <+> w <+> ty) $$ nest 2 (vcat alts)))++           <+ varT (do (c,i) <- exposeT+                       RetAtom <$> if isDeadBinder i ||+                                      (isLocalId i && (i `notElemVarSet` boundVars c))+                                    then varName ^>> ppName WarningColor+                                    else ppVar+                   )++           <+ litT (RetAtom <$> ppSDoc)+           <+ typeT ppTypeModeR+           <+ coercionT ppCoercionModeR+           <+ (castT ppCoreExprR (ppCoercionModeR >>> parenExpr) (,) >>> readerT (\ (_,co) -> if isEmpty co+                                                                                                 then arr fst+                                                                                                 else toFst parenExprExceptApp >>^ \ e -> RetExpr (e <+> castSymbol p <+> co)+                                                                                 ))+           <+ tickT ppSDoc (ppCoreExprR >>> parenExpr) (\ tk e -> RetExpr $ attrP p (text "Tick") $$ nest 2 (tk <+> e))++--------------------------------------------------------------------++ppKindOrType :: PrettyH KindOrType+ppKindOrType = ppKindOrTypeR >>^ normalExpr++ppTypeModeR :: Translate PrettyC HermitM KindOrType RetExpr+ppTypeModeR =+  do opts <- prettyC_options ^<< contextT+     case po_exprTypes opts of+       Omit     -> return RetEmpty+       Abstract -> RetAtom <$> typeSymbol+       _        -> ppKindOrTypeR++ppKindOrTypeR :: Translate PrettyC HermitM KindOrType RetExpr+ppKindOrTypeR = absPathT >>= ppKindOrTypePR+  where+    ppKindOrTypePR :: AbsolutePathH -> Translate PrettyC HermitM KindOrType RetExpr+    ppKindOrTypePR p =+           tyVarT (RetAtom <$> ppVar)+        <+ litTyT (RetAtom <$> ppLitTy)+        <+ appTyT ppKindOrTypeR ppKindOrTypeR (retApp p AppTy_Fun AppTy_Arg)+        <+ funTyT ppKindOrTypeR ppKindOrTypeR (retArrowType p FunTy_Dom FunTy_CoDom)+        <+ forAllTyT ppVar ppKindOrTypeR (retForAll p ForAllTy_Body)+        <+ tyConAppT (forkFirst ppTyCon) (\ _ -> ppKindOrTypeR)+             (\ (pCon,tyCon) tys -> if | isFunTyCon tyCon && length tys == 2 -> let [ty1,ty2] = tys in retArrowType p (TyConApp_Arg 0) (TyConApp_Arg 1) ty1 ty2+                                       | tyCon == listTyCon -> RetAtom $ tyChar p '[' <> (case tys of+                                                                                                []  -> empty+                                                                                                t:_ -> normalExpr t)+                                                                                          <> tyChar p ']'+                                       | isTupleTyCon tyCon -> RetAtom $ tyChar p '(' <> (if null tys+                                                                                               then empty+                                                                                               else foldr1 (\ ty r -> ty <> tyChar p ',' <+> r) (map normalExpr tys)+                                                                                             )+                                                                                          <> tyChar p ')'+                                       | isLiftedTypeKindCon tyCon -> RetAtom $ tyChar p '*'+                                       | otherwise                 -> retApps p TyConApp_Arg pCon tys+             )++--------------------------------------------------------------------++ppCoercion :: PrettyH Coercion+ppCoercion = ppCoercionR >>^ normalExpr++ppCoercionModeR :: Translate PrettyC HermitM Coercion RetExpr+ppCoercionModeR = do p    <- absPathT+                     opts <- prettyC_options ^<< contextT+                     case po_coercions opts of+                       Omit     -> return RetEmpty+                       Abstract -> return (RetAtom $ coercionSymbol p)+                       Show     -> ppCoercionR+                       Kind     -> ppCoKind >>^ (\ k -> RetExpr (coercionSymbol p <+> typeOfSymbol p <+> k))++ppCoercionR :: Translate PrettyC HermitM Coercion RetExpr+ppCoercionR = absPathT >>= ppCoercionPR+  where+    ppCoercionPR :: AbsolutePathH -> Translate PrettyC HermitM Coercion RetExpr+    ppCoercionPR p =+                   coVarCoT (RetAtom <$> ppVar)+                <+ symCoT (ppCoercionR >>> parenExpr >>^ \ co -> RetExpr (coKeyword p "sym" <+> co))+                <+ forAllCoT ppBinderMode ppCoercionR (retForAll p ForAllCo_Body)+                <+ transCoT (ppCoercionR >>> parenExprExceptApp) (ppCoercionR >>> parenExprExceptApp) (\ co1 co2 -> RetExpr (co1 <+> coChar p ';' <+> co2))+                <+ nthCoT (arr show) (ppCoercionR >>> parenExpr) (\ n co -> RetExpr (coKeyword p "nth" <+> coText (p @@ NthCo_Int) n <+> co))+                <+ instCoT (ppCoercionR >>> parenExpr &&& parenExprExceptApp) (ppTypeModeR >>> parenExprExceptApp) (\ (cop1,cop2) ty -> if isEmpty ty+                                                                                                                                         then RetExpr (coText p "inst" <+> cop1)+                                                                                                                                         else RetExpr (cop2 <+> coChar p '@' <+> ty)+                                                                                                                   )+                <+ appCoT ppCoercionR ppCoercionR (retApp p AppCo_Fun AppCo_Arg)+#if __GLASGOW_HASKELL__ > 706+-- TODO: Figure out how to properly pp new branched Axioms and Left/Right Coercions+                <+ reflT (ppTypeModeR >>^ normalExpr) (\ r ty -> RetAtom $ if isEmpty ty then coText p "refl" else coChar p '<' <> coText p (showRole r ++ ":") <> ty <> coChar p '>')+                <+ tyConAppCoT ppTyConCo (const ppCoercionR) (\ r tc -> retApps p TyConApp_Arg $ coText p (showRole r ++ ":") <> tc)+                <+ axiomInstCoT (coAxiomName ^>> ppName CoercionColor) ppSDoc (\ _ -> ppCoercionR >>> parenExpr) (\ ax idx coes -> RetExpr (coText p "axiomInst" <+> ax <+> idx <+> sep coes))+                <+ lrCoT ppSDoc (ppCoercionR >>> parenExpr) (\ lr co -> RetExpr (coercionColor lr <+> co))+                -- TODO: UnivCo and SubCo+                <+ constT (return . RetAtom $ text "Unsupported Coercion Constructor")+#else+                <+ reflT (ppTypeModeR >>^ normalExpr >>^ \ ty -> RetAtom $ if isEmpty ty then coText p "refl" else coChar p '<' <> ty <> coChar p '>')+                <+ tyConAppCoT ppTyConCo (const ppCoercionR) (retApps p TyConApp_Arg)+                <+ unsafeCoT (ppTypeModeR >>> parenExpr) (ppTypeModeR >>> parenExpr) (\ ty1 ty2 -> (if isEmpty ty1 && isEmpty ty2 then RetAtom else RetExpr)+                                                                                                   (coKeyword p "unsafe" <+> ty1 <+> ty2)+                                                     )+                <+ axiomInstCoT (coAxiomName ^>> ppName CoercionColor) (\ _ -> ppCoercionR >>> parenExpr) (\ ax coes -> RetExpr (coText p "axiomInst" <+> ax <+> sep coes))+#endif++ppCoKind :: PrettyH Coercion+ppCoKind = do p <- absPathT+              (coercionKind >>> unPair) ^>> ((ppTypeModeR >>> parenExprExceptApp) *** (ppTypeModeR >>> parenExprExceptApp)) >>^ ( \(ty1,ty2) -> ty1 <+> coText p "~#" <+> ty2)++--------------------------------------------------------------------++ppTypeSig :: PrettyH CoreExpr+ppTypeSig = coercionT ppCoKind <+ (exprKindOrType ^>> ppKindOrType)++------------------------------------------------------------------------------------------------
+ src/HERMIT/PrettyPrinter/Common.hs view
@@ -0,0 +1,479 @@+{-# LANGUAGE CPP, MultiParamTypeClasses, FlexibleInstances, TypeFamilies, DeriveDataTypeable, FlexibleContexts, InstanceSigs #-}++module HERMIT.PrettyPrinter.Common+    ( -- * Documents+      DocH+    , Attr(..)+    , attrP+    , HTML(..)+      -- ** Colors+    , coercionColor+    , idColor+    , keywordColor+    , markColor+    , typeColor+    , ShowOption(..)+    , specialFont+    , SpecialSymbol(..)+    , SyntaxForColor(..)+      -- * Renderers+    , coreRenders+    , renderCode+    , RenderCode(..)+    , renderSpecial+    , RenderSpecial+    , Unicode(..)+      -- * Pretty Printer Traversals+    , PrettyH+    , liftPrettyH+    , PrettyC(..)+    , initPrettyC+    , liftPrettyC+    , TranslateDocH(..)+    , TranslateCoreTCDocHBox(..)+      -- * Pretty Printer Options+    , PrettyOptions(..)+    , updateCoShowOption+    , updateTypeShowOption+    , updateWidthOption+      -- * Utilities+    , hlist+    , vlist+#if __GLASGOW_HASKELL__ > 706+    , showRole+#endif+    ) where++import Data.Char+import Data.Default+import Data.Monoid hiding ((<>))+import qualified Data.Map as M+import Data.Typeable++import HERMIT.Context+import HERMIT.Core+import HERMIT.External+import HERMIT.GHC hiding (($$), (<>), (<+>))+import HERMIT.Kure+import HERMIT.Monad++import Text.PrettyPrint.MarkedHughesPJ as PP++#if __GLASGOW_HASKELL__ > 706+showRole :: Role -> String+showRole Nominal          = "Nominal"+showRole Representational = "Representational"+showRole Phantom          = "Phantom"+#endif++-- A HERMIT document+type DocH = MDoc HermitMark++-- newtype wrapper for proper instance selection+newtype TranslateDocH a = TranslateDocH { unTranslateDocH :: PrettyC -> PrettyH a -> TranslateH a DocH }++data TranslateCoreTCDocHBox = TranslateCoreTCDocHBox (TranslateDocH CoreTC) deriving Typeable++instance Extern (TranslateDocH CoreTC) where+    type Box (TranslateDocH CoreTC) = TranslateCoreTCDocHBox+    box = TranslateCoreTCDocHBox+    unbox (TranslateCoreTCDocHBox i) = i++-- These are the zero-width marks on the document+data HermitMark+        = PushAttr Attr+        | PopAttr+    deriving Show++-- These are the attributes+data Attr = PathAttr AbsolutePathH+          | Color SyntaxForColor+          | SpecialFont+    deriving (Eq, Show)++data SyntaxForColor             -- (suggestion)+        = KeywordColor          -- bold+        | SyntaxColor+        | IdColor+        | CoercionColor+        | TypeColor+        | LitColor+        | WarningColor          -- highlight problems like unbound variables+    deriving (Eq, Show)++attr :: Attr -> DocH -> DocH+attr a p = mark (PushAttr a) <> p <> mark PopAttr++attrP :: AbsolutePathH -> DocH -> DocH+attrP = attr . PathAttr++idColor :: DocH -> DocH+idColor = markColor IdColor++typeColor :: DocH -> DocH+typeColor = markColor TypeColor++coercionColor :: DocH -> DocH+coercionColor = markColor CoercionColor++keywordColor :: DocH -> DocH+keywordColor = markColor KeywordColor++markColor :: SyntaxForColor -> DocH -> DocH+markColor = attr . Color++specialFont :: DocH -> DocH+specialFont = attr SpecialFont++type PrettyH a = Translate PrettyC HermitM a DocH+-- TODO: change monads to something more restricted?++-- | Context for PrettyH translations.+data PrettyC = PrettyC { prettyC_path    :: AbsolutePath Crumb+                       , prettyC_vars    :: VarSet+                       , prettyC_options :: PrettyOptions+                       }++------------------------------------------------------------------------++instance ReadPath PrettyC Crumb where+  absPath :: PrettyC -> AbsolutePath Crumb+  absPath = prettyC_path+  {-# INLINE absPath #-}++instance ExtendPath PrettyC Crumb where+  (@@) :: PrettyC -> Crumb -> PrettyC+  c @@ n = c { prettyC_path = prettyC_path c @@ n }+  {-# INLINE (@@) #-}++instance AddBindings PrettyC where+  addHermitBindings :: [(Var,HermitBindingSite)] -> PrettyC -> PrettyC+  addHermitBindings vbs c = c { prettyC_vars = foldr (flip extendVarSet) (prettyC_vars c) (map fst vbs) }+                            -- let vhbs = [ (v, (0,b)) | (v,b) <- vbs ] -- TODO: do we care about depth?+                            --  in c { prettyC_bindings = M.fromList vhbs `M.union` prettyC_bindings c }+  {-# INLINE addHermitBindings #-}++-- instance ReadBindings PrettyC where+--   hermitDepth :: PrettyC -> BindingDepth+--   hermitDepth = prettyC_depth++--   hermitBindings :: PrettyC -> M.Map Var HermitBinding+--   hermitBindings = prettyC_bindings+--   {-# INLINE hermitBindings #-}++instance BoundVars PrettyC where+  boundVars :: PrettyC -> VarSet+  boundVars = prettyC_vars++------------------------------------------------------------------------++liftPrettyH :: (ReadBindings c, ReadPath c Crumb) => PrettyOptions -> PrettyH a -> Translate c HermitM a DocH+liftPrettyH = liftContext . liftPrettyC++liftPrettyC :: (ReadBindings c, ReadPath c Crumb) => PrettyOptions -> c -> PrettyC+liftPrettyC opts c = PrettyC { prettyC_path    = absPath c+                             , prettyC_vars    = boundVars c+                             , prettyC_options = opts}++initPrettyC :: PrettyOptions -> PrettyC+initPrettyC opts = PrettyC+                      { prettyC_path    = mempty+                      , prettyC_vars    = emptyVarSet+                      , prettyC_options = opts+                      }++-- These are *recommendations* to the pretty printer.++data PrettyOptions = PrettyOptions+        { po_fullyQualified  :: Bool            -- ^ Do you show fully qualified names?+        , po_exprTypes       :: ShowOption      -- ^ Do you hide types, and type arguments, as <>?+        , po_coercions       :: ShowOption      -- ^ Do you hide coercions?+        , po_typesForBinders :: ShowOption      -- ^ Do you give the types for all bindings?+        , po_focus           :: Maybe PathH     -- ^ This region should be highlighted (is the current focus)+        , po_depth           :: Maybe Int       -- ^ below this depth are ..., Nothing => infinite+        , po_notes           :: Bool            -- ^ notes might be added to output+        , po_ribbon          :: Float+        , po_width           :: Int+        } deriving Show++data ShowOption = Show | Abstract | Omit | Kind deriving (Eq, Ord, Show, Read)++-- Types don't have a Kind showing option.+updateTypeShowOption :: ShowOption -> PrettyOptions -> PrettyOptions+updateTypeShowOption Kind po = po+updateTypeShowOption opt  po = po { po_exprTypes = opt }++updateCoShowOption :: ShowOption -> PrettyOptions -> PrettyOptions+updateCoShowOption opt po  = po { po_coercions = opt }++updateWidthOption :: Int -> PrettyOptions -> PrettyOptions+updateWidthOption w po = po { po_width = w }++instance Default PrettyOptions where+  def = PrettyOptions+        { po_fullyQualified  = False+        , po_exprTypes       = Abstract+        , po_coercions       = Abstract+        , po_typesForBinders = Omit+        , po_focus           = Nothing+        , po_depth           = Nothing+        , po_notes           = False+        , po_ribbon          = 1.2+        , po_width           = 80+        }++-----------------------------------------------------------------++-- The characters for special symbols, which have a special alphabet++data SpecialSymbol+        = LambdaSymbol+        | TypeOfSymbol+        | RightArrowSymbol+        | CastSymbol+        | CoercionSymbol+        | CoercionBindSymbol+        | TypeSymbol+        | TypeBindSymbol+        | ForallSymbol+        deriving (Show, Eq, Ord, Bounded, Enum)++class RenderSpecial a where+        renderSpecial :: SpecialSymbol -> a+++-- This instance is special.  It is used as an index, forming an association list.+-- Thus all of the rhs must be distinct characters.+-- Think of RenderSpecial as a special font.+instance RenderSpecial Char where+        renderSpecial LambdaSymbol        = '\\'  -- lambda+        renderSpecial TypeOfSymbol        = ':'   -- ::+        renderSpecial RightArrowSymbol    = '>'   -- ->+        renderSpecial CastSymbol          = '#'   -- "|>"+        renderSpecial CoercionSymbol      = 'C'   -- <<coercion>>>+        renderSpecial CoercionBindSymbol  = 'c'   -- <<coercion>>>+        renderSpecial TypeSymbol          = 'T'   -- <<type>>>+        renderSpecial TypeBindSymbol      = 't'   -- <<type binding>>+        renderSpecial ForallSymbol        = 'F'   -- forall++newtype ASCII = ASCII String++instance Monoid ASCII where+        mempty = ASCII ""+        mappend (ASCII xs) (ASCII ys) = ASCII (xs ++ ys)++instance RenderSpecial ASCII where+        renderSpecial LambdaSymbol        = ASCII "\\"   -- lambda+        renderSpecial TypeOfSymbol        = ASCII "::"   -- ::+        renderSpecial RightArrowSymbol    = ASCII "->"   -- ->+        renderSpecial CastSymbol          = ASCII "|>"   -- "|>"+        renderSpecial CoercionSymbol      = ASCII "~#"   -- <<coercion>>>+        renderSpecial CoercionBindSymbol  = ASCII "~#"   -- <<coercion binding>>>+        renderSpecial TypeSymbol          = ASCII "*"    -- <<type>>>+        renderSpecial TypeBindSymbol      = ASCII "*"    -- <<type binding>>>+        renderSpecial ForallSymbol        = ASCII "\\/"++newtype Unicode = Unicode Char++instance RenderSpecial Unicode where+        renderSpecial LambdaSymbol        = Unicode '\x03BB'+        renderSpecial TypeOfSymbol        = Unicode '\x2237'     -- called PROPORTION+        renderSpecial RightArrowSymbol    = Unicode '\x2192'+        renderSpecial CastSymbol          = Unicode '\x25B9'+        renderSpecial CoercionSymbol      = Unicode '\x25A0'+        renderSpecial CoercionBindSymbol  = Unicode '\x25A1'+        renderSpecial TypeSymbol          = Unicode '\x25b2'+        renderSpecial TypeBindSymbol      = Unicode '\x25b3'+        renderSpecial ForallSymbol        = Unicode '\x2200'++newtype LaTeX = LaTeX String++instance Monoid LaTeX where+        mempty = LaTeX ""+        mappend (LaTeX xs) (LaTeX ys) = LaTeX (xs ++ ys)++instance RenderSpecial LaTeX where+        renderSpecial LambdaSymbol        = LaTeX "\\ensuremath{\\lambda}"+        renderSpecial TypeOfSymbol        = LaTeX ":\\!:"  -- too wide+        renderSpecial RightArrowSymbol    = LaTeX "\\ensuremath{\\shortrightarrow}"+        renderSpecial CastSymbol          = LaTeX "\\ensuremath{\\triangleright}"+        renderSpecial CoercionSymbol      = LaTeX "\\ensuremath{\\blacksquare}"+        renderSpecial CoercionBindSymbol  = LaTeX "\\ensuremath{\\square}"+        renderSpecial TypeSymbol          = LaTeX "\\ensuremath{\\blacktriangle}"+        renderSpecial TypeBindSymbol      = LaTeX "\\ensuremath{\\vartriangle}"+        renderSpecial ForallSymbol        = LaTeX "\\ensuremath{\\forall}"+++newtype HTML = HTML String++instance Monoid HTML where+        mempty = HTML ""+        mappend (HTML xs) (HTML ys) = HTML (xs ++ ys)++instance RenderSpecial HTML where+        renderSpecial LambdaSymbol        = HTML "&#955;"+        renderSpecial TypeOfSymbol        = HTML "&#8759;"+        renderSpecial RightArrowSymbol    = HTML "&#8594;"+        renderSpecial CastSymbol          = HTML "&#9657;"+        renderSpecial CoercionSymbol      = HTML "&#9632;"+        renderSpecial CoercionBindSymbol  = HTML "&#9633;"+        renderSpecial TypeSymbol          = HTML "&#9650;"+        renderSpecial TypeBindSymbol      = HTML "&#9651;"+        renderSpecial ForallSymbol        = HTML "&#8704;"+++renderSpecialFont :: RenderSpecial a => Char -> Maybe a+renderSpecialFont = fmap renderSpecial . flip M.lookup specialFontMap++specialFontMap :: M.Map Char SpecialSymbol+specialFontMap = M.fromList+                [ (renderSpecial s,s)+                | s <- [minBound..maxBound]+                ]+++class (RenderSpecial a, Monoid a) => RenderCode a where+    rStart :: a+    rStart = mempty++    rEnd :: a+    rEnd = mempty++    rDoHighlight :: Maybe Attr  -- ^ Attr just popped, if any+                 -> [Attr]      -- ^ Attr stack+                 -> a++    rPutStr      :: String -> a++renderCode :: RenderCode a => PrettyOptions -> DocH -> a+renderCode opts doc = rStart `mappend` PP.fullRender PP.PageMode w rib marker (\ _ -> rEnd) doc []+  where+          -- options+          w = po_width opts+          rib = po_ribbon opts++          marker :: RenderCode a => PP.TextDetails HermitMark -> ([Attr] -> a) -> ([Attr]-> a)+          marker m rest as@(SpecialFont:_) = case m of+                  PP.Chr ch   -> special [ch] `mappend` rest as+                  PP.Str str  -> special str `mappend` rest as+                  PP.PStr str -> special str `mappend` rest as+                  PP.Mark PopAttr ->+                        let (a:as') = as in rDoHighlight (Just a) as' `mappend` rest as'+                  PP.Mark (PushAttr _) -> error "renderCode: can not have marks inside special symbols"+          marker m rest as = case m of+                  PP.Chr ch   -> rPutStr [ch] `mappend` rest as+                  PP.Str str  -> rPutStr str `mappend` rest as+                  PP.PStr str -> rPutStr str `mappend` rest as+                  PP.Mark (PushAttr a) ->+                        let as' = a : as in rDoHighlight Nothing as' `mappend` rest as'+                  PP.Mark PopAttr -> do+                        let (a:as') = as in rDoHighlight (Just a) as' `mappend` rest as'++          special txt = mconcat [ code | Just code <- map renderSpecialFont txt ]+++-- Other options for pretty printing:+-- * Does a top level program should function names, or complete listings?++--- Moving the renders back into the core hermit++-------------------------------------------------------------------------------++coreRenders :: [(String, PrettyOptions -> DocH -> String)]+coreRenders =+        [ ("latex", \ opts doc -> latexToString $ renderCode opts doc)+        , ("html", \ opts doc -> let HTML str = renderCode opts doc in str)+        , ("ascii", \ opts doc -> let ASCII str = renderCode opts doc in str)+        , ("debug", \ opts doc -> let DebugPretty str = renderCode opts doc in str)+        ]++-- latexVerbatim :: String -> LaTeX -> LaTeX+-- latexVerbatim str (LaTeX v) = LaTeX (str ++ v)++latexToString :: LaTeX -> String+latexToString (LaTeX orig) = unlines $ map trunkSpaces $ lines orig where+  trunkSpaces txt = case span isSpace txt of+                       ([],rest) -> rest+                       (pre,rest) -> "\\hspace{" ++ show (length pre) ++ "\\hermitspace}" ++ rest++instance RenderCode LaTeX where+        rPutStr txt  = LaTeX txt++        -- Latex throws away PathAttr+        rDoHighlight (Just _) _ = LaTeX "}"+        rDoHighlight _ [] = LaTeX $ "{"+        rDoHighlight _ (Color col:_) = LaTeX $ "{" ++ case col of+                        KeywordColor  -> "\\color{hermit:keyword}"       -- blue+                        SyntaxColor   -> "\\color{hermit:syntax}"        -- red+                        IdColor       -> ""+                        CoercionColor -> "\\color{hermit:coercion}"      -- yellow+                        TypeColor     -> "\\color{hermit:type}"          -- green+                        LitColor      -> "\\color{hermit:lit}"           -- cyan+                        WarningColor  -> "\\color{hermit:warning}"       -- black on yellow+        rDoHighlight o (_:rest) = rDoHighlight o rest++        rEnd = LaTeX "\n" -- \\end{Verbatim}"++{- | Use css to do the colors+ -+ - > <style type="text/css">+ - >  .hermit-syntax {+ - >      color: red;+ - >  </style>+ -}++instance RenderCode HTML where+        rPutStr txt  = HTML txt++        rDoHighlight (Just _) _ = HTML "</span>"+        rDoHighlight _ [] = HTML $ "<span>"+        rDoHighlight _ (Color col:_) = HTML $ case col of+                        KeywordColor  -> "<span class=\"hermit-keyword\">"       -- blue+                        SyntaxColor   -> "<span class=\"hermit-syntax\">"        -- red+                        IdColor       -> "<span>"+                        CoercionColor -> "<span class=\"hermit-coercion\">"      -- yellow+                        TypeColor     -> "<span class=\"hermit-type\">"          -- green+                        LitColor      -> "<span class=\"hermit-lit\">"           -- cyan+                        WarningColor  -> "<span class=\"hermit-warning\">"       -- black on yellow+        rDoHighlight o (_:rest) = rDoHighlight o rest+        rEnd = HTML "\n"+++instance RenderCode ASCII where+        rPutStr txt  = ASCII txt++        rDoHighlight _ _ = ASCII ""++        rEnd = ASCII "\n"++data DebugPretty = DebugPretty String++instance RenderSpecial DebugPretty where+        renderSpecial sym = DebugPretty ("{" ++ show sym ++ "}")++instance Monoid DebugPretty where+        mempty = DebugPretty ""+        mappend (DebugPretty xs) (DebugPretty ys) = DebugPretty $ xs ++ ys++instance RenderCode DebugPretty where+        rStart = DebugPretty "(START)\n"++        rPutStr txt  = DebugPretty txt++        rDoHighlight Nothing stk = DebugPretty $ show (True,stk)+        rDoHighlight (Just _) stk = DebugPretty $ show (False,stk)++        rEnd = DebugPretty "(END)\n"++-------------------------------------------------------------------------------++listify :: (MDoc a -> MDoc a -> MDoc a) -> [MDoc a] -> MDoc a+listify _  []     = PP.text "[]"+listify op (d:ds) = op (PP.text "[ " <> d) (foldr (\e es -> op (PP.text ", " <> e) es) (PP.text "]") ds)++-- | like vcat and hcat, only make the list syntax explicit+vlist, hlist :: [MDoc a] -> MDoc a+vlist = listify ($$)+hlist = listify (<+>)++-------------------------------------------------------------------------------
+ src/HERMIT/PrettyPrinter/GHC.hs view
@@ -0,0 +1,71 @@+-- | Output the raw Expr constructors. Helpful for writing pattern matching rewrites.+module HERMIT.PrettyPrinter.GHC+  ( -- * GHC's standard Pretty-Printer for GHC Core+    ppCoreTC+  , ppModGuts+  , ppCoreProg+  , ppCoreBind+  , ppCoreExpr+  , ppCoreAlt+  , ppKindOrType+  , ppCoercion+  )+where++import Control.Arrow hiding ((<+>))++import Data.Char (isSpace)++import HERMIT.Kure+import HERMIT.Core+import HERMIT.GHC hiding ((<+>), char, text, parens)+import HERMIT.PrettyPrinter.Common++import Text.PrettyPrint.MarkedHughesPJ as PP++---------------------------------------------------------------------------++-- | This pretty printer is just a reflection of GHC's standard pretty printer.+ppCoreTC :: PrettyH CoreTC+ppCoreTC =+          promoteExprT     ppCoreExpr+       <+ promoteProgT     ppCoreProg+       <+ promoteBindT     ppCoreBind+       <+ promoteDefT      ppCoreDef+       <+ promoteModGutsT  ppModGuts+       <+ promoteAltT      ppCoreAlt+       <+ promoteTypeT     ppKindOrType+       <+ promoteCoercionT ppCoercion++-- Use for any GHC structure.+ppSDoc :: Outputable a => PrettyH a+ppSDoc = do dynFlags <- constT getDynFlags+            arr (toDoc . showPpr dynFlags)+    where toDoc s | any isSpace s = parens (text s)+                  | otherwise     = text s++ppModGuts :: PrettyH ModGuts+ppModGuts = mg_binds ^>> ppSDoc++ppCoreProg :: PrettyH CoreProg+ppCoreProg = progToBinds ^>> ppSDoc++ppCoreExpr :: PrettyH CoreExpr+ppCoreExpr = ppSDoc++ppCoreBind :: PrettyH CoreBind+ppCoreBind = ppSDoc++ppCoreAlt :: PrettyH CoreAlt+ppCoreAlt = ppSDoc++ppCoreDef :: PrettyH CoreDef+ppCoreDef = defT ppSDoc ppCoreExpr $ \ i e -> i <+> char '=' <+> e++ppKindOrType :: PrettyH Type+ppKindOrType = ppSDoc++ppCoercion :: PrettyH Coercion+ppCoercion = ppSDoc++---------------------------------------------------------------------------
+ src/HERMIT/Shell/Command.hs view
@@ -0,0 +1,586 @@+{-# LANGUAGE LambdaCase, ScopedTypeVariables, GADTs, FlexibleContexts #-}++module HERMIT.Shell.Command+    ( -- * The HERMIT Command-line Shell+      commandLine+    , unicodeConsole+    , diffDocH+    , diffR+      -- ** Exported for hermit-web+    , performKernelEffect+    , performQuery+    , performShellEffect+    , performMetaCommand+    , cl_kernel_env+    , getFocusPath+    , shellComplete+    , evalScript+    ) where++import Control.Applicative+import Control.Arrow hiding (loop)+import Control.Concurrent+import Control.Concurrent.STM+import Control.Exception.Base hiding (catch)+import Control.Monad.State+import Control.Monad.Error++import Data.Char+import Data.Monoid+import Data.List (intercalate, isInfixOf, isPrefixOf, isSuffixOf, nub, partition)+import qualified Data.Map as M+import Data.Maybe++import HERMIT.Core+import HERMIT.Dictionary+import HERMIT.External+import qualified HERMIT.GHC as GHC+import HERMIT.Interp+import HERMIT.Kernel (queryK)+import HERMIT.Kernel.Scoped hiding (abortS, resumeS)+import HERMIT.Kure+import HERMIT.Monad+import HERMIT.Parser+import HERMIT.PrettyPrinter.Common+import HERMIT.PrettyPrinter.Clean (ppCoreTC)+++import HERMIT.Shell.Dictionary+import HERMIT.Shell.Externals+import HERMIT.Shell.ScriptToRewrite+import HERMIT.Shell.Renderer+import HERMIT.Shell.Types++import System.IO+import System.IO.Temp+import System.Process++-- import System.Console.ANSI+import System.Console.Haskeline hiding (catch)+import System.Console.Terminfo (setupTermFromEnv, getCapability, termColumns, termLines)++----------------------------------------------------------------------------------++catch :: IO a -> (String -> IO a) -> IO a+catch = catchJust (\ (err :: IOException) -> return (show err))++cl_putStr :: MonadIO m => String -> CLM m ()+cl_putStr str = do+    st <- get+    liftIO $ cl_render st stdout (cl_pretty_opts st) (Left str)++cl_putStrLn :: MonadIO m => String -> CLM m ()+cl_putStrLn = cl_putStr . (++"\n")++fixWindow :: MonadIO m => CLM m ()+fixWindow = do+    st <- get+    -- check to make sure new path is still inside window+    focusPath <- getFocusPath+    -- move the window in two cases:+    --  1. window path is not prefix of focus path+    --  2. window path is empty (since at the top level we only show type sigs)+    {- when (not (isPrefixOf (cl_window st) focusPath) || null (cl_window st))+       $ put $ st { cl_window = focusPath } -}+    put $ st { cl_window = focusPath } -- TODO: temporary until we figure out a better highlight interface++getFocusPath :: MonadIO m => CLM m PathH+getFocusPath = get >>= \ st -> liftM concat $ prefixFailMsg "getFocusPath - pathS failed: " $ pathS (cl_kernel st) (cl_cursor st)++showWindow :: MonadIO m => CLM m ()+showWindow = do+    fixWindow+    st <- get+    focusPath <- getFocusPath+    let skernel = cl_kernel st+        ppOpts = (cl_pretty_opts st) { po_focus = Just focusPath }+    -- No not show focus while loading+    ifM (gets cl_running_script)+        (return ())+        (iokm2clm' "Rendering error: "+                   (liftIO . cl_render st stdout ppOpts . Right)+                   (toASTS skernel (cl_cursor st) >>= \ ast ->+                        queryK (kernelS skernel) ast (extractT $ pathT (cl_window st) $ liftPrettyH ppOpts $ cl_pretty st) (cl_kernel_env st))+        )++-------------------------------------------------------------------------------++data CompletionType = ConsiderC       -- considerable constructs and (deprecated) bindingOfT+                    | BindingOfC      -- bindingOfT+                    | BindingGroupOfC -- bindingGroupOfT+                    | RhsOfC          -- rhsOfT+                    | OccurrenceOfC   -- occurrenceOfT+                    | InlineC         -- complete with names that can be inlined+                    | CommandC        -- complete using dictionary commands (default)+                    | AmbiguousC [CompletionType]  -- completionType function needs to be more specific+    deriving (Show)++-- TODO: reverse rPrev and parse it, to better figure out what possiblities are in context?+--       for instance, completing "any-bu (inline " should be different than completing just "inline "+--       this would also allow typed completion?+completionType :: String -> CompletionType+completionType = go . dropWhile isSpace+    where go rPrev = case [ ty | (nm, ty) <- opts, reverse nm `isPrefixOf` rPrev ] of+                        []  -> CommandC+                        [t] -> t+                        ts  -> AmbiguousC ts+          opts = [ ("inline"          , InlineC  )+                 , ("consider"        , ConsiderC)+                 , ("binding-of"      , BindingOfC)+                 , ("binding-group-of", BindingGroupOfC)+                 , ("rhs-of"          , RhsOfC)+                 , ("occurrence-of"   , OccurrenceOfC)+                 ]++completionQuery :: CommandLineState -> CompletionType -> IO (TranslateH CoreTC [String])+completionQuery _ ConsiderC       = return $ bindingOfTargetsT       >>^ GHC.varSetToStrings >>^ map ('\'':) >>^ (++ map fst considerables) -- the use of bindingOfTargetsT here is deprecated+completionQuery _ OccurrenceOfC   = return $ occurrenceOfTargetsT    >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery _ BindingOfC      = return $ bindingOfTargetsT       >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery _ BindingGroupOfC = return $ bindingGroupOfTargetsT  >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery _ RhsOfC          = return $ rhsOfTargetsT           >>^ GHC.varSetToStrings >>^ map ('\'':)+completionQuery _ InlineC         = return $ promoteT inlineTargetsT >>^                         map ('\'':)+completionQuery s CommandC        = return $ pure (M.keys (cl_dict s))+-- Need to modify opts in completionType function. No key can be a suffix of another key.+completionQuery _ (AmbiguousC ts) = do+    putStrLn "\nCannot tab complete: ambiguous completion type."+    putStrLn $ "Possibilities: " ++ intercalate ", " (map show ts)+    return (pure [])++shellComplete :: MVar CommandLineState -> String -> String -> IO [Completion]+shellComplete mvar rPrev so_far = do+    st <- readMVar mvar+    targetQuery <- completionQuery st (completionType rPrev)+    -- (liftM.liftM) (map simpleCompletion . nub . filter (so_far `isPrefixOf`))+    --     $ queryS (cl_kernel st) (cl_cursor (cl_session st)) targetQuery+    -- TODO: I expect you want to build a silent version of the kernal_env for this query+    cl <- catchM (queryS (cl_kernel st) targetQuery (cl_kernel_env st) (cl_cursor st)) (\_ -> return [])+    return $ (map simpleCompletion . nub . filter (so_far `isPrefixOf`)) cl++setRunningScript :: MonadIO m => Bool -> CLM m ()+setRunningScript b = modify $ \st -> st { cl_running_script = b }++banner :: String+banner = unlines+    [ "===================== Welcome to HERMIT ======================"+    , "HERMIT is a toolkit for the interactive transformation of GHC"+    , "core language programs. Documentation on HERMIT can be found"+    , "on the HERMIT web page at:"+    , "http://www.ittc.ku.edu/csdl/fpg/software/hermit.html"+    , ""+    , "You have just loaded the interactive shell. To exit, type "+    , "\"abort\" or \"resume\" to abort or resume GHC compilation."+    , ""+    , "Type \"help\" for instructions on how to list or search the"+    , "available HERMIT commands."+    , ""+    , "To get started, you could try the following:"+    , "  - type \"consider 'foo\", where \"foo\" is a function"+    , "    defined in the module;"+    , "  - type \"set-pp-type Show\" to display full type information;"+    , "  - type \"info\" for more information about the current node;"+    , "  - to descend into a child node, type the name of the child"+    , "    (\"info\" includes a list of children of the current node);"+    , "  - to ascend, use the \"up\" command;"+    , "  - type \"log\" to display an activity log."+    , "=============================================================="+    ]++getTermDimensions :: IO (Int, Int)+getTermDimensions = do+    term <- setupTermFromEnv+    let w = fromMaybe 80 $ getCapability term termColumns+        h = fromMaybe 30 $ getCapability term termLines+    return (w,h)++-- | The first argument includes a list of files to load.+commandLine :: MonadIO m => [GHC.CommandLineOption] -> Behavior -> [External] -> CLM m ()+commandLine opts behavior exts = do+    let dict = mkDict $ shell_externals ++ exts+        ws_complete = " ()"+        (flags, filesToLoad) = partition (isPrefixOf "-") opts++    (w,h) <- liftIO getTermDimensions++    -- initialize shell-instance specific parts of the state+    -- TODO: move into another transformer layer?+    initState <- get+    let clState = initState { cl_version     = VersionStore { vs_graph = [] , vs_tags = [] }+                            , cl_scripts     = []+                            , cl_dict        = dict+                            , cl_pretty_opts = (cl_pretty_opts initState) { po_width = w }+                            , cl_height      = h+                            }+    put clState++    completionMVar <- liftIO $ newMVar clState++    let loop :: (MonadIO m, MonadException m) => CLM (InputT m) ()+        loop = do+            st <- get+            let SAST n = cl_cursor st+            mLine <- if cl_nav st+                     then liftIO getNavCmd+                     else do liftIO $ modifyMVar_ completionMVar (const $ return st) -- so the completion can get the current state+                             lift $ getInputLine $ "hermit<" ++ show n ++ "> "++            case mLine of+                Nothing          -> performMetaCommand Resume+                Just ('-':'-':_) -> loop+                Just line        -> if all isSpace line+                                    then loop+                                    else (evalScript line `ourCatch` cl_putStrLn) >> loop++    -- Display the banner+    if any (`elem` ["-v0", "-v1"]) flags+        then return ()+        else cl_putStrLn banner++    -- Load and run any scripts+    setRunningScript True+    sequence_ [ performMetaCommand $ case fileName of+                 "abort"  -> Abort+                 "resume" -> Resume+                 _        -> loadAndRun fileName+              | fileName <- reverse filesToLoad+              , not (null fileName)+              ] `ourCatch` \ msg -> cl_putStrLn $ "Booting Failure: " ++ msg+    setRunningScript False++    -- Start the CLI+    showWindow+    let settings = setComplete (completeWordWithPrev Nothing ws_complete (shellComplete completionMVar)) defaultSettings+    (r,s) <- get >>= liftIO . runInputTBehavior behavior settings . flip runCLM loop+    either throwError (\v -> put s >> return v) r++ourCatch :: MonadIO m => CLM m () -> (String -> CLM m ()) -> CLM m ()+ourCatch m failure = catchM m $ \ msg -> ifM (gets cl_failhard) (performQuery Display >> cl_putStrLn msg >> abort) (failure msg)++evalScript :: MonadIO m => String -> CLM m ()+evalScript = parseScriptCLM >=> runScript++parseScriptCLM :: Monad m => String -> CLM m Script+parseScriptCLM = either fail return . parseScript++runScript :: MonadIO m => Script -> CLM m ()+runScript = mapM_ runExprH++runExprH :: MonadIO m => ExprH -> CLM m ()+runExprH expr = do+    dict <- gets cl_dict+    runKureM (\case+                 KernelEffect effect -> performKernelEffect effect expr+                 ShellEffect effect  -> performShellEffect effect+                 QueryFun query      -> performQuery query+                 MetaCommand meta    -> performMetaCommand meta+             )+             fail+             (interpExprH dict interpShellCommand expr)++-------------------------------------------------------------------------------++-- TODO: This can be refactored. We always showWindow. Also, Perhaps return a modifier, not ()+--   UPDATE: Not true.  We don't always showWindow.+-- TODO: All of these should through an exception if they fail to execute the command as given.++performKernelEffect :: MonadIO m => KernelEffect -> ExprH -> CLM m ()+performKernelEffect (Apply rr) expr = do+    st <- get++    let sk = cl_kernel st+        kEnv = cl_kernel_env st++    sast' <- prefixFailMsg "Rewrite failed: " $ applyS sk rr kEnv (cl_cursor st)++    let commit = put (newSAST expr sast' st) >> showWindow++    if cl_corelint st+        then do ast' <- toASTS sk sast'+                liftIO (queryK (kernelS sk) ast' lintModuleT kEnv)+                >>= runKureM (\ warns -> putStrToConsole warns >> commit)+                             (\ errs  -> liftIO (deleteS sk sast') >> fail errs)+        else commit++performKernelEffect (Pathfinder t) expr = do+    st <- get+    -- An extension to the Path+    p <- prefixFailMsg "Cannot find path: " $ queryS (cl_kernel st) t (cl_kernel_env st) (cl_cursor st)+    ast <- prefixFailMsg "Path is invalid: " $ modPathS (cl_kernel st) (<> p) (cl_kernel_env st) (cl_cursor st)+    put $ newSAST expr ast st+    showWindow++performKernelEffect (Direction dir) expr = do+    st <- get+    ast <- prefixFailMsg "Invalid move: " $ modPathS (cl_kernel st) (moveLocally dir) (cl_kernel_env st) (cl_cursor st)+    put $ newSAST expr ast st+    showWindow++performKernelEffect BeginScope expr = do+        st <- get+        ast <- beginScopeS (cl_kernel st) (cl_cursor st)+        put $ newSAST expr ast st+        showWindow++performKernelEffect EndScope expr = do+        st <- get+        ast <- endScopeS (cl_kernel st) (cl_cursor st)+        put $ newSAST expr ast st+        showWindow++performKernelEffect (Delete sast) _ = gets cl_kernel >>= flip deleteS sast++performKernelEffect (CorrectnessCritera q) expr = do+        st <- get+        -- TODO: Again, we may want a quiet version of the kernel_env+        modFailMsg (\ err -> unparseExprH expr ++ " [exception: " ++ err ++ "]")+                 $ queryS (cl_kernel st) q (cl_kernel_env st) (cl_cursor st)+        putStrToConsole $ unparseExprH expr ++ " [correct]"++-------------------------------------------------------------------------------++performShellEffect :: MonadIO m => ShellEffect -> CLM m ()+performShellEffect (CLSModify f) = do+    st <- get+    opt <- liftIO (fmap Right (f st) `catch` \ str -> return (Left str))+    case opt of+        Right st' -> put st' >> showWindow+        Left err  -> fail err++-------------------------------------------------------------------------------++performQuery :: MonadIO m => QueryFun -> CLM m ()+performQuery (QueryString q) = do+    st <- get+    str <- prefixFailMsg "Query failed: " $ queryS (cl_kernel st) q (cl_kernel_env st) (cl_cursor st)+    putStrToConsole str++performQuery (QueryDocH q) = do+    st <- get+    doc <- prefixFailMsg "Query failed: " $ queryS (cl_kernel st) (q (initPrettyC $ cl_pretty_opts st) $ cl_pretty st) (cl_kernel_env st) (cl_cursor st)+    liftIO $ cl_render st stdout (cl_pretty_opts st) (Right doc)++performQuery (Inquiry f) = do+    st <- get+    str <- liftIO $ f st+    putStrToConsole str++-- These two need to use Inquiry+-- performQuery (Message msg) = liftIO (putStrLn msg)+-- Explicit calls to display should work no matter what the loading state is.+performQuery Display = do+    running_script_st <- gets cl_running_script+    setRunningScript False+    showWindow+    setRunningScript running_script_st++-------------------------------------------------------------------------------++performMetaCommand :: MonadIO m => MetaCommand -> CLM m ()+performMetaCommand (SeqMeta ms) = mapM_ performMetaCommand ms+performMetaCommand Abort  = abort+performMetaCommand Resume = do+    st <- get+    sast' <- applyS (cl_kernel st) occurAnalyseAndDezombifyR (cl_kernel_env st) (cl_cursor st)+    resume sast'++performMetaCommand Continue = get >>= continue+performMetaCommand (Diff s1 s2) = do+    st <- get++    ast1 <- toASTS (cl_kernel st) s1+    ast2 <- toASTS (cl_kernel st) s2+    let getDoc ast = liftIO (queryK (kernelS $ cl_kernel st)+                                    ast+                                    (extractT $ pathT [ModGuts_Prog] $ liftPrettyH (cl_pretty_opts st) $ cl_pretty st)+                                    (cl_kernel_env st)) >>= runKureM return fail+        getCmds sast | sast == s1 = []+                     | otherwise = case [ (f,c) | (f,c,to) <- vs_graph (cl_version st), to == sast ] of+                                    [(sast',cmd)] -> unparseExprH cmd : getCmds sast'+                                    _ -> ["error: history broken!"] -- should be impossible++    cl_putStrLn "Commands:"+    cl_putStrLn "========="+    cl_putStrLn $ unlines $ reverse $ getCmds s2++    doc1 <- getDoc ast1+    doc2 <- getDoc ast2++    r <- diffDocH (cl_pretty_opts st) doc1 doc2++    cl_putStrLn "Diff:"+    cl_putStrLn "====="+    cl_putStr r++performMetaCommand (Dump fileName renderer width) = do+    st <- get+    case lookup renderer shellRenderers of+      Just r -> do doc <- prefixFailMsg "Bad renderer option: " $+                            queryS (cl_kernel st) (liftPrettyH (cl_pretty_opts st) $ cl_pretty st) (cl_kernel_env st) (cl_cursor st)+                   liftIO $ do h <- openFile fileName WriteMode+                               r h ((cl_pretty_opts st) { po_width = width }) (Right doc)+                               hClose h+      _ -> fail "dump: bad pretty-printer or renderer option"++performMetaCommand (LoadFile scriptName fileName) =+  do putStrToConsole $ "Loading \"" ++ fileName ++ "\"..."+     res <- liftIO $ try (readFile fileName)+     case res of+       Left (err :: IOException) -> fail ("IO error: " ++ show err)+       Right str -> do script <- parseScriptCLM str+                       modify $ \ st -> st {cl_scripts = (scriptName,script) : cl_scripts st}+                       putStrToConsole ("Script \"" ++ scriptName ++ "\" loaded successfully from \"" ++ fileName ++ "\".")++performMetaCommand (SaveFile fileName) =+  do version <- gets cl_version+     putStrToConsole $ "[saving " ++ fileName ++ "]"+     -- no checks to see if you are clobering; be careful+     liftIO $ writeFile fileName $ showGraph (vs_graph version) (vs_tags version) (SAST 0)++performMetaCommand (ScriptToRewrite rewriteName scriptName) =+  do script <- lookupScript scriptName+     st <- get+     dict' <- iokm2clm "script-to-rewrite failed: " (return $ addScriptToDict rewriteName script (cl_dict st))+     put (st {cl_dict = dict'})+     putStrToConsole ("Rewrite \"" ++ rewriteName ++ "\" defined successfully.")++performMetaCommand (DefineScript scriptName str) =+  do script <- parseScriptCLM str+     modify $ \ st -> st {cl_scripts = (scriptName,script) : cl_scripts st}+     putStrToConsole ("Script \"" ++ scriptName ++ "\" defined successfully.")++performMetaCommand (RunScript scriptName) =+  do script <- lookupScript scriptName+     running_script_st <- gets cl_running_script+     setRunningScript True+     runScript script `catchError` (\ err -> setRunningScript running_script_st >> throwError err)+     setRunningScript running_script_st+     putStrToConsole ("Script \"" ++ scriptName ++ "\" ran successfully.")+     showWindow++performMetaCommand (SaveScript fileName scriptName) =+  do script <- lookupScript scriptName+     putStrToConsole $ "Saving script \"" ++ scriptName ++ "\" to file \"" ++ fileName ++ "\"."+     liftIO $ writeFile fileName $ unparseScript script+     putStrToConsole $ "Save successful."++lookupScript :: Monad m => ScriptName -> CLM m Script+lookupScript scriptName = do scripts <- gets cl_scripts+                             case lookup scriptName scripts of+                               Nothing     -> fail $ "No script of name " ++ scriptName ++ " is loaded."+                               Just script -> return script++-------------------------------------------------------------------------------++-- TODO: merge with cl_putStr defn+putStrToConsole :: MonadIO m => String -> CLM m ()+putStrToConsole str = ifM (gets cl_running_script)+                          (return ())+                          (cl_putStrLn str)++--------------------------------------------------------++getNavCmd :: IO (Maybe String)+getNavCmd = do+        b_in <- hGetBuffering stdin+        hSetBuffering stdin NoBuffering+        b_out <- hGetBuffering stdin+        hSetBuffering stdout NoBuffering+        ec_in <- hGetEcho stdin+        hSetEcho stdin False+        putStr "(navigation mode; use arrow keys, escape to quit, '?' for help)"+        r <- readCh []+        putStr "\n"+        hSetBuffering stdin b_in+        hSetBuffering stdout b_out+        hSetEcho stdin ec_in+        return r+  where+   readCh xs = do+        x <- getChar+        let str = xs ++ [x]+        (fromMaybe reset $ lookup str cmds) str++   reset _ = do+        putStr "\BEL"+        readCh []++   res str _ = return (Just str)++   cmds = [ ("\ESC" , \ str -> ifM (hReady stdin)+                                   (readCh str)+                                   (return $ Just "command-line"))+          , ("\ESC[" , readCh)+          , ("\ESC[A", res "up")+          , ("\ESC[B", res "down")+          , ("\ESC[C", res "right")+          , ("\ESC[D", res "left")+          , ("?",      res "nav-commands")+          , ("f",      res "step")+          ] +++          [ (show n, res (show n)) | n <- [0..9] :: [Int] ]++----------------------------------------------------------------------------------------------++cl_kernel_env  :: CommandLineState -> HermitMEnv+cl_kernel_env st =+    let out str = do (r,_) <- liftIO $ runCLM st $ cl_putStrLn str+                     either (\case CLError msg -> fail msg+                                   _           -> fail "resume/abort/continue called from cl_putStrLn (impossible!)")+                            return r++    in  mkHermitMEnv $ \ msg -> case msg of+                DebugTick    msg'      -> do+                        c <- liftIO $ tick (cl_tick st) msg'+                        out $ "<" ++ show c ++ "> " ++ msg'+                DebugCore  msg' cxt core -> do+                        out $ "[" ++ msg' ++ "]"+                        doc :: DocH <- apply (cl_pretty st) (liftPrettyC (cl_pretty_opts st) cxt) (inject core)+                        liftIO $ cl_render st stdout (cl_pretty_opts st) (Right doc)++-- tick counter+tick :: TVar (M.Map String Int) -> String -> IO Int+tick var msg = atomically $ do+        m <- readTVar var+        let c = case M.lookup msg m of+                Nothing -> 1+                Just x  -> x + 1+        writeTVar var (M.insert msg c m)+        return c++----------------------------------------------------------------------------------------------++-- TODO: this should be in PrettyPrinter.Common, but is here because it relies on+--       unicodeConsole to get nice colored diffs. We can either switch to straight unicode+--       renderer and give up on color, or come up with a clever solution.+diffDocH :: (MonadCatch m, MonadIO m) => PrettyOptions -> DocH -> DocH -> m String+diffDocH opts doc1 doc2 =+    liftAndCatchIO $+        withSystemTempFile "A.dump" $ \ fp1 h1 ->+            withSystemTempFile "B.dump" $ \ fp2 h2 ->+                withSystemTempFile "AB.diff" $ \ fp3 h3 -> do+                    unicodeConsole h1 opts (Right doc1)+                    hFlush h1+                    unicodeConsole h2 opts (Right doc2)+                    hFlush h2+                    let cmd = unwords ["diff", "-b", "-U 5", fp1, fp2]+                        p = (shell cmd) { std_out = UseHandle h3 , std_err = UseHandle h3 }+                    (_,_,_,h) <- createProcess p+                    _ <- waitForProcess h+                    res <- readFile fp3+                    -- strip out some of the diff lines+                    return $ unlines [ l | l <- lines res, not (fp1 `isInfixOf` l || fp2 `isInfixOf` l)+                                                         , not ("@@" `isPrefixOf` l && "@@" `isSuffixOf` l) ]++-- TODO: again this should be elsewhere, but is here because diffDocH is here.+diffR :: Injection a CoreTC => PrettyOptions -> String -> RewriteH a -> RewriteH a+diffR opts msg rr = do+    let pp = extractT $ liftPrettyH opts ppCoreTC+        runDiff b a = do+            doc1 <- return b >>> pp+            doc2 <- return a >>> pp+            r <- diffDocH opts doc1 doc2+            return a >>> traceR (msg ++ " diff:\n" ++ r)++    -- Be careful to only run the rr once, in case it has side effects.+    (e,r) <- idR &&& attemptM rr+    either fail (runDiff e) r+
+ src/HERMIT/Shell/Dictionary.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE ScopedTypeVariables #-}+module HERMIT.Shell.Dictionary+    ( mkDict+    , pp_dictionary+    ) where++import Data.List+import Data.Map (Map, fromList, toList)++import HERMIT.Kure+import HERMIT.External++import HERMIT.PrettyPrinter.Common+import qualified HERMIT.PrettyPrinter.AST as AST+import qualified HERMIT.PrettyPrinter.Clean as Clean+import qualified HERMIT.PrettyPrinter.GHC as GHCPP++--------------------------------------------------------------------------++-- | Create a dictionary from a list of 'External's.+mkDict :: [External] -> Dictionary+mkDict externs = toDictionary externs'+  where+        msg = layoutTxt 60 (map (show . fst) dictionaryOfTags)+        externs' = externs +++                [ external "help" (help_command externs' "help")+                    [ "(this message)" ] .+ Query .+ Shell+                , external "help" (help_command externs')+                    ([ "help <command>|<category>|categories|all|<search-string>"+                     , "Displays help about a command, or all commands in a category."+                     , "Multiple items may match."+                     , ""+                     , "Categories: " ++ head msg+                     ] ++ map ("            " ++) (tail msg))  .+ Query .+ Shell+                ]++--------------------------------------------------------------------------++-- | The pretty-printing dictionaries.+pp_dictionary :: Map String (PrettyH CoreTC)+pp_dictionary = fromList+        [ ("clean",  Clean.ppCoreTC)+        , ("ast",    AST.ppCoreTC)+        , ("ghc",    GHCPP.ppCoreTC)+        ]++--------------------------------------------------------------------------++make_help :: [External] -> [String]+make_help = concatMap snd . toList . toHelp++help_command :: [External] -> String -> String+help_command exts m+        | [(ct :: CmdTag,"")] <- reads m+        = unlines $ make_help $ filter (tagMatch ct) exts+help_command exts "all"+        = unlines $ make_help exts+help_command _ "categories" = unlines $+                [ "Categories" ] +++                [ "----------" ] +++                [ txt ++ " " ++ replicate (16 - length txt) '.' ++ " " ++ desc+                | (cmd,desc) <- dictionaryOfTags+                , let txt = show cmd+                ]++help_command exts m = unlines $ make_help $ pathPrefix m+    where pathPrefix p = filter (isInfixOf p . externName) exts++layoutTxt :: Int -> [String] -> [String]+layoutTxt n (w1:w2:ws) | length w1 + length w2 >= n = w1 : layoutTxt n (w2:ws)+                       | otherwise = layoutTxt n ((w1 ++ " " ++ w2) : ws)+layoutTxt _ other = other++--------------------------------------------------------------------------+
+ src/HERMIT/Shell/Externals.hs view
@@ -0,0 +1,265 @@+{-# LANGUAGE ScopedTypeVariables #-}++module HERMIT.Shell.Externals where++import Control.Applicative++import Data.Monoid+import Data.List (intercalate)+import qualified Data.Map as M++import HERMIT.Context+import HERMIT.Kure+import HERMIT.External+import HERMIT.Interp+import HERMIT.Kernel.Scoped+import HERMIT.Parser+import HERMIT.PrettyPrinter.Common++import HERMIT.Shell.Dictionary+import HERMIT.Shell.Renderer+import HERMIT.Shell.Types++----------------------------------------------------------------------------------++-- | Interpret a boxed thing as one of the four possible shell command types.+interpShellCommand :: [Interp ShellCommand]+interpShellCommand =+  [ interp $ \ (RewriteCoreBox rr)           -> KernelEffect (Apply rr)+  , interp $ \ (RewriteCoreTCBox rr)         -> KernelEffect (Apply rr)+  , interp $ \ (BiRewriteCoreBox br)         -> KernelEffect (Apply $ forwardT br)+  , interp $ \ (CrumbBox cr)                 -> KernelEffect (Pathfinder (return (mempty @@ cr) :: TranslateH CoreTC LocalPathH))+  , interp $ \ (PathBox p)                   -> KernelEffect (Pathfinder (return p :: TranslateH CoreTC LocalPathH))+  , interp $ \ (TranslateCorePathBox tt)     -> KernelEffect (Pathfinder tt)+  , interp $ \ (TranslateCoreTCPathBox tt)   -> KernelEffect (Pathfinder tt)+  , interp $ \ (StringBox str)               -> QueryFun (message str)+  , interp $ \ (TranslateCoreStringBox tt)   -> QueryFun (QueryString tt)+  , interp $ \ (TranslateCoreTCStringBox tt) -> QueryFun (QueryString tt)+  , interp $ \ (TranslateCoreTCDocHBox tt)   -> QueryFun (QueryDocH $ unTranslateDocH tt)+  , interp $ \ (TranslateCoreCheckBox tt)    -> KernelEffect (CorrectnessCritera tt)+  , interp $ \ (TranslateCoreTCCheckBox tt)  -> KernelEffect (CorrectnessCritera tt)+  , interp $ \ (effect :: KernelEffect)      -> KernelEffect effect+  , interp $ \ (effect :: ShellEffect)       -> ShellEffect effect+  , interp $ \ (query :: QueryFun)           -> QueryFun query+  , interp $ \ (meta :: MetaCommand)         -> MetaCommand meta+  ]++shell_externals :: [External]+shell_externals = map (.+ Shell)+   [+     external "resume"          Resume    -- HERMIT Kernel Exit+       [ "stops HERMIT; resumes compile" ]+   , external "abort"           Abort     -- UNIX Exit+       [ "hard UNIX-style exit; does not return to GHC; does not save" ]+   , external "continue"        Continue  -- Shell Exit, but not HERMIT+       [ "exits shell; resumes HERMIT" ]+   , external "gc"              (Delete . SAST)+       [ "garbage-collect a given AST; does not remove from command log" ]+   , external "gc"              (CLSModify gc)+       [ "garbage-collect all ASTs except for the initial and current AST" ]+   , external "display"         Display+       [ "redisplays current state" ]+   , external "left"            (Direction L)+       [ "move to the next child"]+   , external "right"           (Direction R)+       [ "move to the previous child"]+   , external "up"              (Direction U)+       [ "move to the parent node"]+   , external "down"            (deprecatedIntToPathT 0 :: TranslateH Core LocalPathH) -- TODO: short-term solution+       [ "move to the first child"]+   , external "navigate"        (CLSModify $ \ st -> return $ st { cl_nav = True })+       [ "switch to navigate mode" ]+   , external "command-line"    (CLSModify $ \ st -> return $ st { cl_nav = False })+       [ "switch to command line mode" ]+   , external "set-window"      (CLSModify setWindow)+       [ "fix the window to the current focus" ]+   , external "top"             (Direction T)+       [ "move to root of current scope" ]+   , external "back"            (CLSModify $ versionCmd Back)+       [ "go back in the derivation" ]                                          .+ VersionControl+   , external "log"             (Inquiry showDerivationTree)+       [ "go back in the derivation" ]                                          .+ VersionControl+   , external "step"            (CLSModify $ versionCmd Step)+       [ "step forward in the derivation" ]                                     .+ VersionControl+   , external "goto"            (CLSModify . versionCmd . Goto)+       [ "goto a specific step in the derivation" ]                             .+ VersionControl+   , external "goto"            (CLSModify . versionCmd . GotoTag)+       [ "goto a named step in the derivation" ]+   , external "tag"             (CLSModify . versionCmd . AddTag)+       [ "tag <label> names the current AST with a label" ]                     .+ VersionControl+   , external "diff"            (\ s1 s2 -> Diff (SAST s1) (SAST s2))+       [ "show diff of two ASTs" ]                                              .+ VersionControl+   , external "set-fail-hard" (\ bStr -> CLSModify $ \ st ->+        case reads bStr of+            [(b,"")] -> return $ st { cl_failhard = b }+            _        -> return st )+       [ "set-fail-hard <True|False>; False by default"+       , "any rewrite failure causes compilation to abort" ]+   , external "set-auto-corelint" (\ bStr -> CLSModify $ \ st ->+        case reads bStr of+            [(b,"")] -> return $ st { cl_corelint = b }+            _        -> return st )+       [ "set-auto-corelint <True|False>; False by default"+       , "run core lint type-checker after every rewrite, reverting on failure" ]+   , external "set-pp"           (\ name -> CLSModify $ \ st ->+       case M.lookup name pp_dictionary of+         Nothing -> do+            putStrLn $ "List of Pretty Printers: " ++ intercalate ", " (M.keys pp_dictionary)+            return st+         Just pp -> return $ st { cl_pretty = pp })+       [ "set the pretty printer"+       , "use 'set-pp ls' to list available pretty printers" ]+   , external "set-pp-renderer"    changeRenderer+       [ "set the output renderer mode"]+   , external "set-pp-renderer"    showRenderers+       [ "set the output renderer mode"]+   , external "dump"    Dump+       [ "dump <filename> <pretty-printer> <renderer> <width>"]+   , external "set-pp-width" (\ w -> CLSModify $ \ st ->+        return $ st { cl_pretty_opts = updateWidthOption w (cl_pretty_opts st) })+       ["set the width of the screen"]+   , external "set-pp-type" (\ str -> CLSModify $ \ st ->+        case reads str :: [(ShowOption,String)] of+            [(opt,"")] -> return $ st { cl_pretty_opts = updateTypeShowOption opt (cl_pretty_opts st) }+            _          -> return st)+       ["set how to show expression-level types (Show|Abstact|Omit)"]+   , external "set-pp-coercion" (\ str -> CLSModify $ \ st ->+        case reads str :: [(ShowOption,String)] of+            [(opt,"")] -> return $ st { cl_pretty_opts = updateCoShowOption opt (cl_pretty_opts st) }+            _          -> return st)+       ["set how to show coercions (Show|Abstact|Omit)"]+   , external "{"   BeginScope+       ["push current lens onto a stack"]       -- tag as internal+   , external "}"   EndScope+       ["pop a lens off a stack"]               -- tag as internal+   , external "load"  LoadFile+       ["load <script-name> <file-name> : load a HERMIT script from a file and save it under the specified name."]+   , external "load-and-run"  loadAndRun+       ["load-and-run <file-name> : load a HERMIT script from a file and run it immediately."]+   , external "save"  SaveFile+       ["save <filename> : save the current complete derivation into a file."]+   , external "save-script" SaveScript+       ["save-script <filename> <script name> : save a loaded or manually defined script to a file." ]+   , external "load-as-rewrite" (\ rewriteName fileName -> SeqMeta [LoadFile rewriteName fileName, ScriptToRewrite rewriteName rewriteName])+       ["load-as-rewrite <rewrite-name> <filepath> : load a HERMIT script from a file, and convert it to a rewrite."+       ,"Note that there are significant limitations on the commands the script may contain."] .+ Experiment .+ TODO+   , external "script-to-rewrite" ScriptToRewrite+       ["script-to-rewrite <rewrite-name> <script-name> : create a new rewrite from a pre-loaded (or manually defined) HERMIT script."+       ,"Note that there are significant limitations on the commands the script may contain."] .+ Experiment .+ TODO+   , external "define-script" DefineScript+       ["Define a new HERMIT script and bind it to a name."+       ,"Note that any names in the script will not be resolved until the script is *run*."+       ,"Example usage: define-script \"MyScriptName\" \"any-td beta-reduce ; let-subst ; bash\""]+   , external "define-rewrite" (\ name str -> SeqMeta [DefineScript name str, ScriptToRewrite name name])+       ["Define a new HERMIT rewrite and bind it to a name."+       ,"Note that this also saves the input script under the same name."+       ,"Example usage: define-rewrite \"MyRewriteName\" \"let-subst >>> bash\""]+   , external "run-script" RunScript+       ["Run a pre-loaded (or manually defined) HERMIT script."+       ,"Note that any names in the script will not be resolved until the script is *run*." ]+   , external "display-scripts" displayScripts+       ["Display all loaded scripts."]+     -- TODO: maybe add a "list-scripts" as well that just lists the names of loaded scripts?+   ]++gc :: CommandLineState -> IO CommandLineState+gc st = do+    let k = cl_kernel st+        cursor = cl_cursor st+        initSAST = cl_initSAST st+    asts <- listS k+    mapM_ (deleteS k) [ sast | sast <- asts, sast `notElem` [cursor, initSAST] ]+    return st++----------------------------------------------------------------------------------++setWindow :: CommandLineState -> IO CommandLineState+setWindow st = do+    paths <- concat <$> pathS (cl_kernel st) (cl_cursor st)+    return $ st { cl_window = paths }++--------------------------------------------------------++versionCmd :: VersionCmd -> CommandLineState -> IO CommandLineState+versionCmd whereTo st =+    case whereTo of+        Goto n -> do+            all_nds <- listS (cl_kernel st)+            if SAST n `elem` all_nds+                then return $ st { cl_cursor = SAST n }+                else fail $ "Cannot find AST #" ++ show n ++ "."+        GotoTag tag -> case lookup tag (vs_tags (cl_version st)) of+                        Just sast -> return $ st { cl_cursor = sast }+                        Nothing   -> fail $ "Cannot find tag " ++ show tag ++ "."+        Step -> do+            let ns = [ edge | edge@(s,_,_) <- vs_graph (cl_version st), s == cl_cursor st ]+            case ns of+                [] -> fail "Cannot step forward (no more steps)."+                [(_,cmd,d) ] -> do+                    putStrLn $ "step : " ++ unparseExprH cmd+                    return $ st { cl_cursor = d }+                _ -> fail "Cannot step forward (multiple choices)"+        Back -> do+            let ns = [ edge | edge@(_,_,d) <- vs_graph (cl_version st), d == cl_cursor st ]+            case ns of+                []         -> fail "Cannot step backwards (no more steps)."+                [(s,cmd,_) ] -> do+                    putStrLn $ "back, unstepping : " ++ unparseExprH cmd+                    return $ st { cl_cursor = s }+                _          -> fail "Cannot step backwards (multiple choices, impossible!)."+        AddTag tag -> do+            return $ st { cl_version = (cl_version st) { vs_tags = (tag, cl_cursor st) : vs_tags (cl_version st) }}++-------------------------------------------------------------------------------++showDerivationTree :: CommandLineState -> IO String+showDerivationTree st = return $ unlines $ showRefactorTrail graph tags 0 me+  where+          graph = [ (a,[unparseExprH b],c) | (SAST a,b,SAST c) <- vs_graph (cl_version st) ]+          tags  = [ (n,nm) | (nm,SAST n) <- vs_tags (cl_version st) ]+          SAST me = cl_cursor st++showRefactorTrail :: (Eq a, Show a) => [(a,[String],a)] -> [(a,String)] -> a -> a -> [String]+showRefactorTrail db tags a me =+        case [ (b,c) | (a0,b,c) <- db, a == a0 ] of+           [] -> [show' 3 a ++ " " ++ dot ++ tags_txt]+           ((b,c):bs) ->+                      [show' 3 a ++ " " ++ dot ++ (if not (null bs) then "->" else "") ++ tags_txt ] +++                      ["    " ++ "| " ++ txt | txt <- b ] +++                      showRefactorTrail db tags c me +++                      if null bs+                      then []+                      else [] :+                          showRefactorTrail [ (a',b',c') | (a',b',c') <- db+                                                          , not (a == a' && c == c')+                                                          ]  tags a me++  where+          dot = if a == me then "*" else "o"+          show' n x = replicate (n - length (show a)) ' ' ++ show x+          tags_txt = concat [ ' ' : txt+                            | (n,txt) <- tags+                            , n == a+                            ]+++showGraph :: [(SAST,ExprH,SAST)] -> [(String,SAST)] -> SAST -> String+showGraph graph tags this@(SAST n) =+        (if length paths > 1 then "tag " ++ show n ++ "\n" else "") +++        concat (intercalate+                ["goto " ++ show n ++ "\n"]+                [ [ unparseExprH b ++ "\n" ++ showGraph graph tags c ]+                | (b,c) <- paths+                ])+  where+          paths = [ (b,c) | (a,b,c) <- graph, a == this ]++-------------------------------------------------------------------------------++displayScripts :: QueryFun+displayScripts = Inquiry (return . showScripts . cl_scripts)++showScripts :: [(ScriptName,Script)] -> String+showScripts = concatMap (\ (name,script) -> name ++ ": " ++ unparseScript script ++ "\n\n")++-------------------------------------------------------------------------------
+ src/HERMIT/Shell/Renderer.hs view
@@ -0,0 +1,78 @@+module HERMIT.Shell.Renderer where++import Data.List (isPrefixOf)+import Data.Monoid++import HERMIT.Kure+import HERMIT.PrettyPrinter.Common++import HERMIT.Shell.Types++import System.Console.ANSI+import System.IO+++showRenderers :: QueryFun+showRenderers = message $ "set-renderer " ++ show (map fst shellRenderers)++changeRenderer :: String -> ShellEffect+changeRenderer renderer = CLSModify $ \ st ->+        case lookup renderer shellRenderers of+          Nothing -> return st          -- TODO: should fail with message+          Just r  -> return $ st { cl_render = r }++-------------------------------------------------------------------------------++newtype UnicodeTerminal = UnicodeTerminal (Handle -> Maybe PathH -> IO ())++instance RenderSpecial UnicodeTerminal where+        renderSpecial sym = UnicodeTerminal $ \ h _ -> hPutStr h [ch]+                where (Unicode ch) = renderSpecial sym++instance Monoid UnicodeTerminal where+        mempty = UnicodeTerminal $ \ _ _ -> return ()+        mappend (UnicodeTerminal f1) (UnicodeTerminal f2) = UnicodeTerminal $ \ h p -> f1 h p >> f2 h p++shellRenderers :: [(String,Handle -> PrettyOptions -> Either String DocH -> IO ())]+shellRenderers = [ ("unicode-terminal", unicodeConsole) ]+              ++ [ (nm, \ h opts -> either (hPutStr h) (hPutStr h . fn opts)) | (nm,fn) <- coreRenders ]++unicodeConsole :: Handle -> PrettyOptions -> Either String DocH -> IO ()+unicodeConsole h _    (Left str)  = hPutStr h str+unicodeConsole h opts (Right doc) = let UnicodeTerminal r = renderCode opts doc+                                     in r h $ po_focus opts++doSGR :: [SGR] -> UnicodeTerminal+doSGR cmds = UnicodeTerminal $ \ h _ -> hSetSGR h cmds++undoSGRWith :: [SGR] -> [Attr] -> UnicodeTerminal+undoSGRWith cmds stk = doSGR cmds `mappend` rDoHighlight Nothing stk++setHighlight :: PathH -> Handle -> Maybe PathH -> IO ()+setHighlight _ _ Nothing   = return ()+setHighlight p h (Just fp) = hSetSGR h (if fp `isPrefixOf` p then [ SetUnderlining SingleUnderline ] else [ Reset ])++instance RenderCode UnicodeTerminal where+        rPutStr txt  = UnicodeTerminal $ \ h _ -> hPutStr h txt++        -- TODO: if we want an inplace CLI... rStart = UnicodeTerminal $ \ h _ -> hClearScreen h >> hSetCursorPosition h 0 0+        rEnd = UnicodeTerminal $ \ h _ -> hSetSGR h [ Reset ] >> hPutStrLn h ""++        -- anything that doesn't just change the foreground color needs to end itself cleanly+        rDoHighlight (Just (Color KeywordColor)) stk = undoSGRWith [SetConsoleIntensity NormalIntensity] stk+        rDoHighlight (Just (Color WarningColor)) stk = undoSGRWith [SetSwapForegroundBackground False] stk+        rDoHighlight _ [] = doSGR [ Reset ]+        rDoHighlight _ (Color col:_) =+            doSGR $ case col of+                        KeywordColor  -> [ SetConsoleIntensity BoldIntensity+                                         , SetColor Foreground Dull Blue+                                         ]+                        SyntaxColor   -> [ SetColor Foreground Dull Red ]+                        IdColor       -> [] -- equivalent to Reset+                        CoercionColor -> [ SetColor Foreground Dull Yellow ]+                        TypeColor     -> [ SetColor Foreground Dull Green ]+                        LitColor      -> [ SetColor Foreground Dull Cyan ]+                        WarningColor  -> [ SetSwapForegroundBackground True, SetColor Foreground Vivid Yellow ]+-- TODO: enable        rDoHighlight _ (PathAttr p:_) = UnicodeTerminal $ setHighlight $ snocPathToPath p+        rDoHighlight o (_:rest) = rDoHighlight o rest+
+ src/HERMIT/Shell/ScriptToRewrite.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE ScopedTypeVariables #-}++module HERMIT.Shell.ScriptToRewrite+  ( -- * Converting Scripts to Rewrites+    addScriptToDict+  )+where++import Control.Arrow+import Control.Monad (liftM)++import Data.Dynamic+import Data.Map++import HERMIT.Context(LocalPathH)+import HERMIT.Kure+import HERMIT.External+import HERMIT.Interp+import HERMIT.Parser(Script)++import HERMIT.PrettyPrinter.Common(TranslateCoreTCDocHBox(..))+import HERMIT.Shell.Types++------------------------------------++data UnscopedScriptR+              = ScriptBeginScope+              | ScriptEndScope+              | ScriptPrimUn PrimScriptR+              | ScriptUnsupported String++data ScopedScriptR+              = ScriptScope [ScopedScriptR]+              | ScriptPrimSc PrimScriptR++data PrimScriptR+       = ScriptRewriteHCore (RewriteH Core)+       | ScriptPath PathH+       | ScriptTranslateHCorePath (TranslateH Core LocalPathH)+++-- TODO: Hacky parsing, needs cleaning up+unscopedToScopedScriptR :: forall m. Monad m => [UnscopedScriptR] -> m [ScopedScriptR]+unscopedToScopedScriptR = parse+  where+    parse :: [UnscopedScriptR] -> m [ScopedScriptR]+    parse []     = return []+    parse (y:ys) = case y of+                     ScriptUnsupported msg -> fail ("script contains " ++ msg ++ " which cannot be converted to a rewrite.")+                     ScriptPrimUn pr       -> (ScriptPrimSc pr :) <$> parse ys+                     ScriptBeginScope      -> do (rs,zs) <- parseUntilEndScope ys+                                                 (ScriptScope rs :) <$> parse zs+                     ScriptEndScope        -> fail "unmatched end-of-scope."++    parseUntilEndScope :: Monad m => [UnscopedScriptR] -> m ([ScopedScriptR], [UnscopedScriptR])+    parseUntilEndScope []     = fail "missing end-of-scope."+    parseUntilEndScope (y:ys) = case y of+                                  ScriptEndScope        -> return ([],ys)+                                  ScriptBeginScope      -> do (rs,zs)  <- parseUntilEndScope ys+                                                              first (ScriptScope rs :) <$> parseUntilEndScope zs+                                  ScriptPrimUn pr       -> first (ScriptPrimSc pr :) <$> parseUntilEndScope ys+                                  ScriptUnsupported msg -> fail ("script contains " ++ msg ++ ", which cannot be converted to a rewrite.")++-----------------------------------++interpScriptR :: [Interp UnscopedScriptR]+interpScriptR =+  [ interp (\ (RewriteCoreBox r)           -> ScriptPrimUn $ ScriptRewriteHCore r)+  , interp (\ (RewriteCoreTCBox _)         -> ScriptUnsupported "rewrites that traverse types and coercions") -- TODO+  , interp (\ (BiRewriteCoreBox br)        -> ScriptPrimUn $ ScriptRewriteHCore $ forwardT br)+  , interp (\ (CrumbBox cr)                -> ScriptPrimUn $ ScriptPath [cr])+  , interp (\ (PathBox p)                  -> ScriptPrimUn $ ScriptPath (snocPathToPath p))+  , interp (\ (TranslateCorePathBox t)     -> ScriptPrimUn $ ScriptTranslateHCorePath t)+  , interp (\ (effect :: KernelEffect)     -> case effect of+                                                BeginScope -> ScriptBeginScope+                                                EndScope   -> ScriptEndScope+                                                _          -> ScriptUnsupported "Kernel effects" )+  , interp (\ (_ :: MetaCommand)           -> ScriptUnsupported "meta commands")+  , interp (\ (_ :: ShellEffect)           -> ScriptUnsupported "shell effects")+  , interp (\ (_ :: QueryFun)              -> ScriptUnsupported "queries")+  , interp (\ (TranslateCoreStringBox _)   -> ScriptUnsupported "queries")+  , interp (\ (TranslateCoreTCStringBox _) -> ScriptUnsupported "queries")+  , interp (\ (TranslateCoreTCDocHBox _)   -> ScriptUnsupported "queries")+  , interp (\ (TranslateCoreCheckBox _)    -> ScriptUnsupported "predicates")+  , interp (\ (StringBox _)                -> ScriptUnsupported "messages")+  ]++-----------------------------------++scopedScriptsToRewrite :: [ScopedScriptR] -> RewriteH Core+scopedScriptsToRewrite []        = idR+scopedScriptsToRewrite (x : xs)  = let rest = scopedScriptsToRewrite xs+                                   in case x of+                                        ScriptScope ys   -> scopedScriptsToRewrite ys >>> rest+                                        ScriptPrimSc pr  -> case pr of+                                                              ScriptRewriteHCore r       -> r >>> rest+                                                              ScriptPath p               -> pathR p rest+                                                              ScriptTranslateHCorePath t -> do p <- t+                                                                                               localPathR p rest++-----------------------------------++-----------------------------------++-- | Insert a script into the 'Dictionary'.+addScriptToDict :: Monad m => ScriptName -> Script -> Dictionary -> m Dictionary+addScriptToDict nm scr dict =+  do unscoped <- mapM (interpExprH dict interpScriptR) scr+     scoped   <- unscopedToScopedScriptR unscoped+     let+         dyn = toDyn (box $ scopedScriptsToRewrite scoped)++         alteration :: Maybe [Dynamic] -> Maybe [Dynamic]+         alteration Nothing     = Just [dyn]+         alteration (Just dyns) = Just (dyn:dyns)++     return $ alter alteration nm dict++-----------------------------------++-- I find it annoying that Functor is not a superclass of Monad.+(<$>) :: Monad m => (a -> b) -> m a -> m b+(<$>) = liftM+{-# INLINE (<$>) #-}++-----------------------------------
+ src/HERMIT/Shell/Types.hs view
@@ -0,0 +1,201 @@+{-# LANGUAGE KindSignatures, GADTs, FlexibleContexts, TypeFamilies, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}++module HERMIT.Shell.Types where++import Control.Concurrent.STM+import Control.Monad.State+import Control.Monad.Error++import Data.Dynamic+import qualified Data.Map as M++import HERMIT.Context+import HERMIT.Kure+import HERMIT.External+import qualified HERMIT.GHC as GHC+import HERMIT.Kernel.Scoped+import HERMIT.Parser+import HERMIT.PrettyPrinter.Common++import System.IO++----------------------------------------------------------------------------------++-- | There are four types of commands.+data ShellCommand =  KernelEffect KernelEffect -- ^ Command that modifies the state of the (scoped) kernel.+                  |  ShellEffect  ShellEffect  -- ^ Command that modifies the state of the shell.+                  |  QueryFun     QueryFun     -- ^ Command that queries the AST with a Translate (read only).+                  |  MetaCommand  MetaCommand  -- ^ Command that otherwise controls HERMIT (abort, resume, save, etc).++-- GADTs can't have docs on constructors. See Haddock ticket #43.+-- | KernelEffects are things that affect the state of the Kernel+--   - Apply a rewrite (giving a whole new lower-level AST).+--   - Change the current location using a computed path.+--   - Change the currect location using directions.+--   - Begin or end a scope.+--   - Delete an AST+--   - Run a precondition or other predicate that must not fail.+data KernelEffect :: * where+   Apply      :: (Injection GHC.ModGuts g, Walker HermitC g) => RewriteH g              -> KernelEffect+   Pathfinder :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g LocalPathH -> KernelEffect+   Direction  ::                                                Direction               -> KernelEffect+   BeginScope ::                                                                           KernelEffect+   EndScope   ::                                                                           KernelEffect+   Delete     ::                                                SAST                    -> KernelEffect+   CorrectnessCritera :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g () -> KernelEffect+   deriving Typeable++instance Extern KernelEffect where+   type Box KernelEffect = KernelEffect+   box i = i+   unbox i = i++data ShellEffect :: * where+   CLSModify :: (CommandLineState -> IO CommandLineState) -> ShellEffect+   deriving Typeable++data QueryFun :: * where+   QueryString   :: (Injection GHC.ModGuts g, Walker HermitC g)+                 => TranslateH g String                                   -> QueryFun+   QueryDocH     :: (PrettyC -> PrettyH CoreTC -> TranslateH CoreTC DocH) -> QueryFun+   Display       ::                                                          QueryFun+   Inquiry       :: (CommandLineState -> IO String)                       -> QueryFun+   deriving Typeable++message :: String -> QueryFun+message str = Inquiry (const $ return str)++instance Extern QueryFun where+   type Box QueryFun = QueryFun+   box i = i+   unbox i = i++type RewriteName = String++data MetaCommand+   = Resume+   | Abort+   | Continue -- exit the shell, but don't abort/resume+   | Diff SAST SAST+   | Dump String String Int+   | LoadFile ScriptName FilePath  -- load a file on top of the current node+   | SaveFile FilePath+   | ScriptToRewrite RewriteName ScriptName+   | DefineScript ScriptName String+   | RunScript ScriptName+   | SaveScript FilePath ScriptName+   | SeqMeta [MetaCommand]+   deriving Typeable++-- | A composite meta-command for running a loaded script immediately.+--   The script is given the same name as the filepath.+loadAndRun :: FilePath -> MetaCommand+loadAndRun fp = SeqMeta [LoadFile fp fp, RunScript fp]++instance Extern MetaCommand where+    type Box MetaCommand = MetaCommand+    box i = i+    unbox i = i++data VersionCmd = Back                  -- back (up) the derivation tree+                | Step                  -- down one step; assumes only one choice+                | Goto Int              -- goto a specific node, if possible+                | GotoTag String        -- goto a specific named tag+                | AddTag String         -- add a tag+        deriving Show++instance Extern ShellEffect where+    type Box ShellEffect = ShellEffect+    box i = i+    unbox i = i++----------------------------------------------------------------------------------++data CLException = CLAbort+                 | CLResume SAST+                 | CLContinue CommandLineState+                 | CLError String++instance Error CLException where+    strMsg = CLError++newtype CLM m a = CLM { unCLM :: ErrorT CLException (StateT CommandLineState m) a }+    deriving (MonadIO, MonadError CLException, MonadState CommandLineState)++-- | Our own custom instance of Monad for CLM m so we don't have to depend on+-- newtype deriving to do the right thing for fail.+instance Monad m => Monad (CLM m) where+    return = CLM . return+    (CLM m) >>= k = CLM (m >>= unCLM . k)+    fail = CLM . throwError . CLError++abort :: Monad m => CLM m ()+abort = throwError CLAbort++resume :: Monad m => SAST -> CLM m ()+resume = throwError . CLResume++continue :: Monad m => CommandLineState -> CLM m ()+continue = throwError . CLContinue++instance MonadTrans CLM where+    lift = CLM . lift . lift++instance Monad m => MonadCatch (CLM m) where+    -- law: fail msg `catchM` f == f msg+    -- catchM :: m a -> (String -> m a) -> m a+    catchM m f = do+        st <- get+        (r,st') <- lift $ runCLM st m+        case r of+            Left err -> case err of+                            CLError msg -> f msg+                            other -> throwError other -- rethrow abort/resume+            Right v  -> put st' >> return v++runCLM :: CommandLineState -> CLM m a -> m (Either CLException a, CommandLineState)+runCLM s = flip runStateT s . runErrorT . unCLM++-- TODO: Come up with names for these, and/or better characterise these abstractions.+iokm2clm' :: MonadIO m => String -> (a -> CLM m b) -> IO (KureM a) -> CLM m b+iokm2clm' msg ret m = liftIO m >>= runKureM ret (throwError . CLError . (msg ++))++iokm2clm :: MonadIO m => String -> IO (KureM a) -> CLM m a+iokm2clm msg = iokm2clm' msg return++iokm2clm'' :: MonadIO m => IO (KureM a) -> CLM m a+iokm2clm'' = iokm2clm ""++data VersionStore = VersionStore+    { vs_graph       :: [(SAST,ExprH,SAST)]+    , vs_tags        :: [(String,SAST)]+    }++newSAST :: ExprH -> SAST -> CommandLineState -> CommandLineState+newSAST expr sast st = st { cl_cursor = sast+                          , cl_version = (cl_version st) { vs_graph = (cl_cursor st, expr, sast) : vs_graph (cl_version st) }+                          }++-- Session-local issues; things that are never saved.+data CommandLineState = CommandLineState+    { cl_cursor         :: SAST                                     -- ^ the current AST+    , cl_pretty         :: PrettyH CoreTC                           -- ^ which pretty printer to use+    , cl_pretty_opts    :: PrettyOptions                            -- ^ the options for the pretty printer+    , cl_render         :: Handle -> PrettyOptions -> Either String DocH -> IO () -- ^ the way of outputing to the screen+    , cl_height         :: Int                                      -- ^ console height, in lines+    , cl_nav            :: Bool                                     -- ^ keyboard input the nav panel+    , cl_running_script :: Bool                                     -- ^ if running a script+    , cl_tick           :: TVar (M.Map String Int)                  -- ^ the list of ticked messages+    , cl_corelint       :: Bool                                     -- ^ if true, run Core Lint on module after each rewrite+    , cl_failhard       :: Bool                                     -- ^ if true, abort on *any* failure+    , cl_window         :: PathH                                    -- ^ path to beginning of window, always a prefix of focus path in kernel+    -- these four should be in a reader+    , cl_dict           :: Dictionary+    , cl_scripts        :: [(ScriptName,Script)]+    , cl_kernel         :: ScopedKernel+    , cl_initSAST       :: SAST+    -- and the version store+    , cl_version        :: VersionStore+    }++type ScriptName = String
+ src/HERMIT/Syntax.hs view
@@ -0,0 +1,59 @@+module HERMIT.Syntax+   (+      -- * Utility Predicates for lexing Identifiers+      -- ** Lexing HERMIT Scripts+      isScriptIdFirstChar,+      isScriptIdChar,+      isScriptInfixIdChar,+      -- ** Lexing Core Fragments+      isCoreIdFirstChar,+      isCoreIdChar,+      isCoreInfixIdChar+   )+where++import Data.Char (isAlphaNum, isAlpha)++---------------------------------------------------------------------++-- | Characters that are valid as the leading character of an identifier in a HERMIT script.+isScriptIdFirstChar :: Char -> Bool+isScriptIdFirstChar c = isAlphaNum c || c `elem` "$_:."++-- | Characters that are valid identifier elements (a superset of 'isScriptIdFirstChar') in a HERMIT script.+isScriptIdChar :: Char -> Bool+isScriptIdChar c = isScriptIdFirstChar c || isScriptInfixIdChar c || c `elem` "'"+  -- infix identifiers can appear in dictionary names+  -- square brackets can appear in dictionary names (specifically, list instances).  However, we don't include them here because that would require us to always place spaces around [ ] when defining lists.  As a work-around, the user can place "" around any such names.++-- | Characters that are valid in infix operators in a HERMIT script.+isScriptInfixIdChar :: Char -> Bool+isScriptInfixIdChar c = c `elem` infixOperatorSymbols+                        -- old: "!£$%^&*-+=@#<>?/.:|"++---------------------------------------------------------------------++-- | Chars that are valid as the leading character of an identifier in a Core fragment.+isCoreIdFirstChar :: Char -> Bool+isCoreIdFirstChar c = c `elem` "_$[]:.=" || isAlpha c++-- | Characters that are valid identifier elements (a superset of 'isCoreIdFirstChar') in a Core fragment.+isCoreIdChar :: Char -> Bool+isCoreIdChar c = isAlphaNum c || isCoreIdFirstChar c || isCoreInfixIdChar c || c `elem` "'[]"+  -- infix identifiers can appear in dictionary names+  -- square brackets can appear in dictionary names (specifically, list instances)++-- | Characters that are valid in infix operators in a Core fragment.+isCoreInfixIdChar :: Char -> Bool+isCoreInfixIdChar c = c `elem` infixOperatorSymbols+                      -- old: "+*/._-:<>"++---------------------------------------------------------------------++-- TODO: Should the set of infix operator symobls be common to both HERMIT scripts and Core fragments?+--       I'm pretty sure the old definition of isCoreInfixIdChar was too limited at least.++infixOperatorSymbols :: [Char]+infixOperatorSymbols = "!£$%^&*-+=@#<>?/.:|"++---------------------------------------------------------------------
+ src/HERMIT/Utilities.hs view
@@ -0,0 +1,40 @@+module HERMIT.Utilities+  ( -- * Utilities+    nodups+  , equivalentBy+  , equivalent+  , whenJust+  )+where++------------------------------------------------------------------------------++-- | Determine if a list contains no duplicated elements.+nodups :: Eq a => [a] -> Bool+nodups []     = True+nodups (a:as) = (a `notElem` as) && nodups as++------------------------------------------------------------------------------++-- Drew: surely this exists generally somewhere?+-- for instance:+--      equivalentBy ((==) `on` length) :: [[a]] -> Bool+-- checks if all lists have the same length++-- | A generalisation of 'equivalent' to any equivalence relation.+--   @equivalent = equivalentBy (==)@+equivalentBy :: (a -> a -> Bool) -> [a] -> Bool+equivalentBy _  []     = True+equivalentBy eq (x:xs) = all (eq x) xs++-- | Determine if all elements of a list are equal.+equivalent :: Eq a => [a] -> Bool+equivalent = equivalentBy (==)++------------------------------------------------------------------------------++-- | Perform the monadic action only in the 'Just' case.+whenJust :: Monad m => (a -> m ()) -> Maybe a -> m ()+whenJust f = maybe (return ()) f++------------------------------------------------------------------------------
− src/Language/HERMIT/Context.hs
@@ -1,231 +0,0 @@-{-# LANGUAGE InstanceSigs, ConstraintKinds, MultiParamTypeClasses #-}--module Language.HERMIT.Context-       ( -- * HERMIT Contexts-         -- ** The Standard Context-         HermitC-       , initHermitC-         -- ** Bindings-       , HermitBindingSite(..)-       , BindingDepth-       , HermitBinding-       , hermitBindingSiteExpr-       , hermitBindingExpr-         -- ** Adding bindings to contexts-       , AddBindings(..)-       , addBindingGroup-       , addLambdaBinding-       , addAltBindings-       , addCaseWildBinding-       , addForallBinding-         -- ** Reading bindings from the context-       , BoundVars(..)-       , boundIn-       , findBoundVars-       , ReadBindings(..)-       , lookupHermitBinding-         -- ** Accessing the Global Reader Environment from the context-       , HasGlobalRdrEnv(..)-         -- ** Accessing GHC rewrite rules from the context-       , HasCoreRules(..)-) where--import Prelude hiding (lookup)-import GhcPlugins hiding (empty)-import Data.Monoid (mempty)-import Data.Map hiding (map, foldr, filter)-import qualified Data.Set as S-import qualified Language.Haskell.TH as TH--import Language.KURE--import Language.HERMIT.Core-import Language.HERMIT.GHC------------------------------------------------------------------------------ | The depth of a binding.  Used, for example, to detect shadowing when inlining.-type BindingDepth = Int----- | HERMIT\'s representation of variable bindings.---   Bound expressions cannot be inlined without checking for shadowing issues (using the depth information).-data HermitBindingSite-        = REC CoreExpr-        | NONREC CoreExpr-        | LAM-        | CASEALT-        | FORALL-        | CASEWILD CoreExpr (AltCon,[Var])  -- ^ We store both the scrutinised expression, and the case alternative 'AltCon' (which can be converted to Constructor or Literal) and variables.--type HermitBinding = (BindingDepth, HermitBindingSite)---- | Retrieve the expression in a 'HermitBindingSite', if there is one.-hermitBindingSiteExpr :: HermitBindingSite -> Maybe CoreExpr-hermitBindingSiteExpr b = case b of-                            REC e        -> Just e-                            NONREC e     -> Just e-                            CASEWILD e _ -> Just e-                            _            -> Nothing---- | Retrieve the expression in a 'HermitBinding', if there is one.-hermitBindingExpr :: HermitBinding -> Maybe CoreExpr-hermitBindingExpr = hermitBindingSiteExpr . snd------------------------------------------------------------------------------ | A class of contexts that can have HERMIT bindings added to them.-class AddBindings c where-  -- | Add a complete set of parrallel bindings to the context.-  --   (Parallel bindings occur in recursive let bindings and case alternatives.)-  --   This can also be used for solitary bindings (e.g. lambdas).-  --   Bindings are added in parallel sets to help with shadowing issues.-  addHermitBindings :: [(Var,HermitBindingSite)] -> c -> c---- | Here the bindings are just discarded.-instance AddBindings (SnocPath crumb) where-  addHermitBindings :: [(Var,HermitBindingSite)] -> SnocPath crumb -> SnocPath crumb-  addHermitBindings _ = id------------------------------------------------- | Add a single binding to the context.-addHermitBinding  :: AddBindings c => Var -> HermitBindingSite -> c -> c-addHermitBinding v bd = addHermitBindings [(v,bd)]---- | Add all bindings in a binding group to a context.-addBindingGroup :: AddBindings c => CoreBind -> c -> c-addBindingGroup (NonRec v e) = addHermitBinding  v (NONREC e)-addBindingGroup (Rec ies)    = addHermitBindings [ (i, REC e) | (i,e) <- ies ]---- | Add a wildcard binding for a specific case alternative.-addCaseWildBinding :: AddBindings c => (Id,CoreExpr,CoreAlt) -> c -> c-addCaseWildBinding (i,e,(con,vs,_)) = addHermitBinding i (CASEWILD e (con,vs))---- | Add a lambda bound variable to a context.---   All that is known is the variable, which may shadow something.---   If so, we don't worry about that here, it is instead checked during inlining.-addLambdaBinding :: AddBindings c => Var -> c -> c-addLambdaBinding v = addHermitBinding v LAM---- | Add the variables bound by a 'DataCon' in a case.---   They are all bound at the same depth.-addAltBindings :: AddBindings c => [Var] -> c -> c-addAltBindings vs = addHermitBindings [ (v, CASEALT) | v <- vs ]---- | Add a universally quantified type variable to a context.-addForallBinding :: AddBindings c => TyVar -> c -> c-addForallBinding v = addHermitBinding v FORALL------------------------------------------------------------------------------ | A class of contexts that stores the set of variables in scope that have been bound during the traversal.-class BoundVars c where-  boundVars :: c -> S.Set Var---- | List all variables bound in the context that match the given name.-findBoundVars :: BoundVars c => TH.Name -> c -> [Var]-findBoundVars nm = filter (cmpTHName2Var nm) . S.toList . boundVars----- | A class of contexts from which HERMIT bindings can be retrieved.-class BoundVars c => ReadBindings c where-  hermitDepth    :: c -> BindingDepth-  hermitBindings :: c -> Map Var HermitBinding---- | Determine if a variable is bound in a context.-boundIn :: ReadBindings c => Var -> c -> Bool-boundIn i c = i `member` hermitBindings c---- | Lookup the binding for a variable in a context.-lookupHermitBinding :: ReadBindings c => Var -> c -> Maybe HermitBinding-lookupHermitBinding v = lookup v . hermitBindings------------------------------------------------------------------------------ | A class of contexts that store GHC rewrite rules.-class HasCoreRules c where-  hermitCoreRules :: c -> [CoreRule]------------------------------------------------------------------------------ | A class of contexts that store the Global Reader Environment.-class HasGlobalRdrEnv c where-  hermitGlobalRdrEnv :: c -> GlobalRdrEnv------------------------------------------------------------------------------ | The HERMIT context, containing all bindings in scope and the current location in the AST.---   The bindings here are lazy by choice, so that we can avoid the cost---   of building the context if we never use it.-data HermitC = HermitC-        { hermitC_bindings       :: Map Var HermitBinding   -- ^ All (important) bindings in scope.-        , hermitC_depth          :: BindingDepth            -- ^ The depth of the bindings.-        , hermitC_path           :: AbsolutePath Crumb      -- ^ The 'AbsolutePath' to the current node from the root.-        , hermitC_globalRdrEnv   :: GlobalRdrEnv            -- ^ The top-level lexical environment.-        , hermitC_coreRules      :: [CoreRule]              -- ^ GHC rewrite RULES.-        }------------------------------------------------------------------------------ | Create the initial HERMIT 'HermitC' by providing a 'ModGuts'.-initHermitC :: ModGuts -> HermitC-initHermitC modGuts = HermitC-                        { hermitC_bindings      = empty-                        , hermitC_depth         = 0-                        , hermitC_path          = mempty-                        , hermitC_globalRdrEnv  = mg_rdr_env modGuts-                        , hermitC_coreRules     = mg_rules modGuts ++ other_rules-                        }--    where other_rules :: [CoreRule]-          other_rules = mg_binds modGuts >>= bindToIdExprs >>= (idCoreRules . fst)------------------------------------------------------------------------------ | Retrieve the 'AbsolutePath' to the current node, from the HERMIT context.-instance ReadPath HermitC Crumb where-  absPath :: HermitC -> AbsolutePath Crumb-  absPath = hermitC_path---- | Extend the 'AbsolutePath' stored in the HERMIT context.-instance ExtendPath HermitC Crumb where-  (@@) :: HermitC -> Crumb -> HermitC-  c @@ n = c { hermitC_path = hermitC_path c @@ n }----------------------------------------------------------------------------instance AddBindings HermitC where-  addHermitBindings :: [(Var,HermitBindingSite)] -> HermitC -> HermitC-  addHermitBindings vbs c = let nextDepth = succ (hermitC_depth c)-                                vhbs      = [ (v, (nextDepth,b)) | (v,b) <- vbs ]-                             in c { hermitC_bindings = fromList vhbs `union` hermitC_bindings c-                                  , hermitC_depth    = nextDepth-                                  }----------------------------------------------------------------------------instance BoundVars HermitC where-  boundVars :: HermitC -> S.Set Var-  boundVars =  keysSet . hermitC_bindings--instance ReadBindings HermitC where-  hermitDepth :: HermitC -> BindingDepth-  hermitDepth = hermitC_depth--  hermitBindings :: HermitC -> Map Var HermitBinding-  hermitBindings = hermitC_bindings----------------------------------------------------------------------------instance HasCoreRules HermitC where-  hermitCoreRules :: HermitC -> [CoreRule]-  hermitCoreRules = hermitC_coreRules----------------------------------------------------------------------------instance HasGlobalRdrEnv HermitC where-  hermitGlobalRdrEnv :: HermitC -> GlobalRdrEnv-  hermitGlobalRdrEnv = hermitC_globalRdrEnv--------------------------------------------------------------------------
− src/Language/HERMIT/Core.hs
@@ -1,293 +0,0 @@-{-# LANGUAGE LambdaCase #-}--module Language.HERMIT.Core-          (-            -- * Generic Data Type-            CoreProg(..)-          , CoreDef(..)-          , CoreTickish-            -- * Conversions to/from 'Core'-          , defsToRecBind-          , defToIdExpr-          , progToBinds-          , bindsToProg-          , bindToIdExprs-            -- * Utilities-          , isCoArg-          , exprTypeOrKind-          , endoFunType-          , funArgResTypes-          , funsWithInverseTypes-          , appCount-            -- * Crumbs-          , Crumb(..)-          , showCrumbs---          , crumbToDeprecatedInt-          , deprecatedLeftSibling-          , deprecatedRightSibling-) where--import GhcPlugins--import Language.KURE.Combinators.Monad-import Language.KURE.MonadCatch--import Data.List (intercalate)--------------------------------------------------------------------------- | A program is a telescope of nested binding groups.---   That is, each binding scopes over the remainder of the program.---   In GHC Core, programs are encoded as ['CoreBind'].---   This data type is isomorphic.-data CoreProg = ProgNil                     -- ^ An empty program.-              | ProgCons CoreBind CoreProg  -- ^ A binding group and the program it scopes over.--infixr 5 `ProgCons`---- | Get the list of bindings in a program.-progToBinds :: CoreProg -> [CoreBind]-progToBinds ProgNil         = []-progToBinds (ProgCons bd p) = bd : progToBinds p--- recursive, don't inline---- | Build a program from a list of bindings.---   Note that bindings earlier in the list are considered scope over bindings later in the list.-bindsToProg :: [CoreBind] -> CoreProg-bindsToProg = foldr ProgCons ProgNil-{-# INLINE bindsToProg #-}---- | Extract the list of identifier/expression pairs from a binding group.-bindToIdExprs :: CoreBind -> [(Id,CoreExpr)]-bindToIdExprs (NonRec v e) = [(v,e)]-bindToIdExprs (Rec bds)    = bds-{-# INLINE bindToIdExprs #-}---- | A (potentially recursive) definition is an identifier and an expression.---   In GHC Core, recursive definitions are encoded as ('Id', 'CoreExpr') pairs.---   This data type is isomorphic.-data CoreDef = Def Id CoreExpr---- | Convert a definition to an identifier/expression pair.-defToIdExpr :: CoreDef -> (Id,CoreExpr)-defToIdExpr (Def v e) = (v,e)-{-# INLINE defToIdExpr #-}---- | Convert a list of recursive definitions into an (isomorphic) recursive binding group.-defsToRecBind :: [CoreDef] -> CoreBind-defsToRecBind = Rec . map defToIdExpr-{-# INLINE defsToRecBind #-}----------------------------------------------------------------------------- | Unlike everything else, there is no synonym for 'Tickish' 'Id' provided by GHC, so we define one.-type CoreTickish = Tickish Id----------------------------------------------------------------------------- | GHC's 'exprType' function throws an error if applied to a 'Type' (but, inconsistently, return a 'Kind' if applied to a type variable).---   This function returns the 'Kind' of a 'Type', but otherwise behaves as 'exprType'.-exprTypeOrKind :: CoreExpr -> Type-exprTypeOrKind (Type t) = typeKind t-exprTypeOrKind e        = exprType e-{-# INLINE exprTypeOrKind #-}---- | Returns @True@ iff the expression is a 'Coercion' expression at its top level.-isCoArg :: CoreExpr -> Bool-isCoArg (Coercion {}) = True-isCoArg _             = False-{-# INLINE isCoArg #-}----------------------------------------------------------------------------- | Count the number of nested applications.-appCount :: CoreExpr -> Int-appCount (App e1 _) = appCount e1 + 1-appCount _          = 0--- don't inline, recursive----------------------------------------------------------------------------- | Return the domain/codomain type of an endofunction expression.-endoFunType :: Monad m => CoreExpr -> m Type-endoFunType f = do (ty1,ty2) <- funArgResTypes f-                   guardMsg (eqType ty1 ty2) ("argument and result types differ.")-                   return ty1-{-# INLINE endoFunType #-}---- | Return the domain and codomain types of a function expression.-funArgResTypes :: Monad m => CoreExpr -> m (Type,Type)-funArgResTypes e = maybe (fail "not a function type.") return (splitFunTy_maybe $ exprType e)-{-# INLINE funArgResTypes #-}---- | Check two expressions have types @a -> b@ and @b -> a@, returning @(a,b)@.-funsWithInverseTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type,Type)-funsWithInverseTypes f g = do (fdom,fcod) <- funArgResTypes f-                              (gdom,gcod) <- funArgResTypes g-                              setFailMsg "functions do not have inverse types." $-                                do guardM (eqType fdom gcod)-                                   guardM (eqType gdom fcod)-                                   return (fdom,fcod)-{-# INLINE funsWithInverseTypes #-}----------------------------------------------------------------------------- | Crumbs record a path through the tree, using descriptive constructor names.-data Crumb =-           -- ModGuts-             ModGuts_Prog-           -- Prog-           | ProgCons_Head | ProgCons_Tail-           -- Bind-           | NonRec_RHS | NonRec_Var-           | Rec_Def Int-           -- Def-           | Def_Id | Def_RHS-           -- Expr-           | Var_Id-           | Lit_Lit-           | App_Fun | App_Arg-           | Lam_Var | Lam_Body-           | Let_Bind | Let_Body-           | Case_Scrutinee | Case_Binder | Case_Type | Case_Alt Int-           | Cast_Expr | Cast_Co-           | Tick_Tick | Tick_Expr-           | Type_Type-           | Co_Co-           -- Alt-           | Alt_Con | Alt_Var Int | Alt_RHS-           -- Type-           | TyVarTy_TyVar-           | LitTy_TyLit-           | AppTy_Fun | AppTy_Arg-           | TyConApp_TyCon | TyConApp_Arg Int-           | FunTy_Dom | FunTy_CoDom-           | ForAllTy_Var | ForAllTy_Body-           -- Coercion-           | Refl_Type-           | TyConAppCo_TyCon | TyConAppCo_Arg Int-           | AppCo_Fun | AppCo_Arg-           | ForAllCo_TyVar | ForAllCo_Body-           | CoVarCo_CoVar-           | AxiomInstCo_Axiom | AxiomInstCo_Index | AxiomInstCo_Arg Int-           | UnsafeCo_Left | UnsafeCo_Right-           | SymCo_Co-           | TransCo_Left | TransCo_Right-           | NthCo_Int | NthCo_Co-           | InstCo_Co | InstCo_Type-           | LRCo_LR | LRCo_Co-           deriving (Eq,Read,Show)-           -- TODO: Write a prettier Show instance---showCrumbs :: [Crumb] -> String-showCrumbs crs = "[" ++ intercalate ", " (map showCrumb crs) ++ "]"---- Note, these should match the external names in Language.HERMIT.Primitive.Navigation.Crumbs-showCrumb :: Crumb -> String-showCrumb = \case-               ModGuts_Prog   -> "prog"-               ProgCons_Head  -> "prog-head"-               ProgCons_Tail  -> "prog-tail"-               NonRec_RHS     -> "nonrec-rhs"-               Rec_Def n      -> "rec-def " ++ show n-               Def_RHS        -> "def-rhs"-               App_Fun        -> "app-fun"-               App_Arg        -> "app-arg"-               Lam_Body       -> "lam-body"-               Let_Bind       -> "let-bind"-               Let_Body       -> "let-body"-               Case_Scrutinee -> "case-expr"-               Case_Type      -> "case-type"-               Case_Alt n     -> "case-alt " ++ show n-               Cast_Expr      -> "cast-expr"-               Cast_Co        -> "cast-co"-               Tick_Expr      -> "tick-expr"-               Alt_RHS        -> "alt-rhs"-               Type_Type      -> "type"-               Co_Co          -> "coercion"-               -- Types-               AppTy_Fun      -> "appTy-fun"-               AppTy_Arg      -> "appTy-arg"-               TyConApp_Arg n -> "tyCon-arg " ++ show n-               FunTy_Dom      -> "fun-dom"-               FunTy_CoDom    -> "fun-cod"-               ForAllTy_Body  -> "forall-body"-               -- Coercions-               Refl_Type         -> "refl-type"-               TyConAppCo_Arg n  -> "coCon-arg " ++ show n-               AppCo_Fun         -> "appCo-fun"-               AppCo_Arg         -> "appCo-arg"-               ForAllCo_Body     -> "coForall-body"-               AxiomInstCo_Arg n -> "axiom-inst " ++ show n-               UnsafeCo_Left     -> "unsafe-left"-               UnsafeCo_Right    -> "unsafe-right"-               SymCo_Co          -> "sym-co"-               TransCo_Left      -> "trans-left"-               TransCo_Right     -> "trans-right"-               NthCo_Co          -> "nth-co"-               InstCo_Co         -> "inst-co"-               InstCo_Type       -> "inst-type"-               LRCo_Co           -> "lr-co"--               _              -> "Warning: Crumb should not be in use!  This is probably Neil's fault."--{---- | Earlier versions of HERMIT used 'Int' as the crumb type.---   This function maps a 'Crumb' back to that corresponding 'Int', for backwards compatibility purposes.-crumbToDeprecatedInt :: Crumb -> Maybe Int-crumbToDeprecatedInt = \case-                          ModGuts_Prog   -> Just 0-                          ProgCons_Bind  -> Just 0-                          ProgCons_Tail  -> Just 1-                          NonRec_RHS     -> Just 0-                          NonRec_Var     -> Nothing-                          Rec_Def n      -> Just n-                          Def_Id         -> Nothing-                          Def_RHS        -> Just 0-                          App_Fun        -> Just 0-                          App_Arg        -> Just 1-                          Lam_Var        -> Nothing-                          Lam_Body       -> Just 0-                          Let_Bind       -> Just 0-                          Let_Body       -> Just 1-                          Case_Scrutinee -> Just 0-                          Case_Binder    -> Nothing-                          Case_Type      -> Nothing-                          Case_Alt n     -> Just (n + 1)-                          Cast_Expr      -> Just 0-                          Cast_Co        -> Nothing-                          Tick_Tick      -> Nothing-                          Tick_Expr      -> Just 0-                          Type_Type      -> Nothing-                          Co_Co          -> Nothing-                          Alt_Con        -> Nothing-                          Alt_Var _      -> Nothing-                          Alt_RHS        -> Just 0--}--- | Converts a 'Crumb' into the 'Crumb' pointing to its left-sibling, if a such a 'Crumb' exists.---   This is for backwards compatibility purposes with the old Int representation.-deprecatedLeftSibling :: Crumb -> Maybe Crumb-deprecatedLeftSibling = \case-                           ProgCons_Tail       -> Just ProgCons_Head-                           Rec_Def n | n > 0   -> Just (Rec_Def (n-1))-                           App_Arg             -> Just App_Fun-                           Let_Body            -> Just Let_Bind-                           Case_Alt n | n == 0 -> Just Case_Scrutinee-                                      | n >  0 -> Just (Case_Alt (n-1))-                           _                   -> Nothing---- | Converts a 'Crumb' into the 'Crumb' pointing to its right-sibling, if a such a 'Crumb' exists.---   This is for backwards compatibility purposes with the old Int representation.-deprecatedRightSibling :: Crumb -> Maybe Crumb-deprecatedRightSibling = \case-                           ProgCons_Head       -> Just ProgCons_Tail-                           Rec_Def n           -> Just (Rec_Def (n+1))-                           App_Fun             -> Just App_Arg-                           Let_Bind            -> Just Let_Body-                           Case_Scrutinee      -> Just (Case_Alt 0)-                           Case_Alt n          -> Just (Case_Alt (n+1))-                           _                   -> Nothing--------------------------------------------------------------------------
− src/Language/HERMIT/Dictionary.hs
@@ -1,151 +0,0 @@-{-# LANGUAGE GADTs, ScopedTypeVariables #-}--module Language.HERMIT.Dictionary-    ( -- * The HERMIT Dictionary-      -- | This is the main namespace. Things tend to be untyped, because the API is accessed via (untyped) names.-      Dictionary-    , externals-    , mkDict-    , pp_dictionary-    , bashR-    , bashDebugR-    ) where--import Control.Arrow--import Data.Dynamic-import Data.List-import Data.Map (Map, fromList, toList)--import Language.HERMIT.Kure-import Language.HERMIT.External--import qualified Language.HERMIT.Primitive.AlphaConversion as Alpha-import qualified Language.HERMIT.Primitive.Debug as Debug-import qualified Language.HERMIT.Primitive.FixPoint as FixPoint-import qualified Language.HERMIT.Primitive.Fold as Fold-import qualified Language.HERMIT.Primitive.GHC as GHC-import qualified Language.HERMIT.Primitive.Inline as Inline-import qualified Language.HERMIT.Primitive.Kure as Kure-import qualified Language.HERMIT.Primitive.Local as Local-import qualified Language.HERMIT.Primitive.Navigation as Navigation-import qualified Language.HERMIT.Primitive.New as New-import qualified Language.HERMIT.Primitive.Unfold as Unfold--import Language.HERMIT.PrettyPrinter.Common-import qualified Language.HERMIT.PrettyPrinter.AST as AST-import qualified Language.HERMIT.PrettyPrinter.Clean as Clean-import qualified Language.HERMIT.PrettyPrinter.GHC as GHCPP-------------------------------------------------------------------------------- | A 'Dictionary' is a collection of 'Dynamic's.---   Looking up a 'Dynamic' (via a 'String' key) returns a list, as there can be multiple 'Dynamic's with the same name.-type Dictionary = Map String [Dynamic]---- | List of all 'External's provided by HERMIT.-externals :: [External]-externals =-       Alpha.externals-    ++ Debug.externals-    ++ FixPoint.externals-    ++ Fold.externals-    ++ GHC.externals-    ++ Inline.externals-    ++ Kure.externals-    ++ Local.externals-    ++ Navigation.externals-    ++ New.externals-    ++ Unfold.externals---- | Create a dictionary from a list of 'External's.-mkDict :: [External] -> Dictionary-mkDict externs = toDictionary externs'-  where-        msg = layoutTxt 60 (map (show . fst) dictionaryOfTags)-        externs' = externs ++-                [ external "help" (help_command externs' "help")-                    [ "(this message)" ] .+ Query .+ Shell-                , external "help" (help_command externs')-                    ([ "help <command>|<category>|categories|all|<search-string>"-                     , "Displays help about a command, or all commands in a category."-                     , "Multiple items may match."-                     , ""-                     , "Categories: " ++ head msg-                     ] ++ map ("            " ++) (tail msg))  .+ Query .+ Shell-                -- Runs every command matching the tag predicate with innermostR (fix point anybuR),-                -- Only fails if all of them fail the first time.-                , external "bash" (bashR externs) (bashHelp externs) .+ Eval .+ Deep .+ Loop-                , external "debug-bash" (bashDebugR True externs)-                    [ "verbose bash - most useful with set-auto-corelint True" ] .+ Eval .+ Deep .+ Loop-                ]-------------------------------------------------------------------------------- | The pretty-printing dictionaries.-pp_dictionary :: Map String (PrettyOptions -> PrettyH CoreTC)-pp_dictionary = fromList-        [ ("clean",  Clean.corePrettyH)-        , ("ast",    AST.corePrettyH)-        , ("ghc",    GHCPP.corePrettyH)-        ]--{---- (This isn't used anywhere currently.)--- | Each pretty printer can suggest some options-pp_opt_dictionary :: Map String PrettyOptions-pp_opt_dictionary = fromList-        [ ("clean", def)-        , ("ast",  def)-        , ("ghc",  def)-        ]--}------------------------------------------------------------------------------make_help :: [External] -> [String]-make_help = concatMap snd . toList . toHelp--help_command :: [External] -> String -> String-help_command exts m-        | [(ct :: CmdTag,"")] <- reads m-        = unlines $ make_help $ filter (tagMatch ct) exts-help_command exts "all"-        = unlines $ make_help exts-help_command _ "categories" = unlines $-                [ "Categories" ] ++-                [ "----------" ] ++-                [ txt ++ " " ++ replicate (16 - length txt) '.' ++ " " ++ desc-                | (cmd,desc) <- dictionaryOfTags-                , let txt = show cmd-                ]--help_command exts m = unlines $ make_help $ pathPrefix m-    where pathPrefix p = filter (isInfixOf p . externName) exts--layoutTxt :: Int -> [String] -> [String]-layoutTxt n (w1:w2:ws) | length w1 + length w2 >= n = w1 : layoutTxt n (w2:ws)-                       | otherwise = layoutTxt n ((w1 ++ " " ++ w2) : ws)-layoutTxt _ other = other------------------------------------------------------------------------------bashPredicate :: CmdTag-bashPredicate = Bash--bashR :: [External] -> RewriteH Core-bashR = bashDebugR False--bashDebugR :: Bool -> [External] -> RewriteH Core-bashDebugR debug exts =-    setFailMsg "bashR: nothing to do."-    $ innermostR $ orR [ if debug then rr >>> Debug.observeR (externName e) else rr-                       | (e,rr) <- matchingExternals bashPredicate exts ]--bashHelp :: [External] -> [String]-bashHelp exts =-    "Iteratively apply the following rewrites until nothing changes:"-    : [ externName e | (e,_ :: RewriteH Core) <- matchingExternals bashPredicate exts ]-----------------------------------------------------------------------------
− src/Language/HERMIT/External.hs
@@ -1,430 +0,0 @@-{-# LANGUAGE TypeFamilies, DeriveDataTypeable, FlexibleContexts, GADTs, TypeSynonymInstances, FlexibleInstances #-}--module Language.HERMIT.External-       (-       -- * Externals-         External-       , ExternalName-       , ExternalHelp-       , externName-       , externFun-       , externHelp-       , toDictionary-       , toHelp-       , external-       , Extern(..)-       , matchingExternals-       -- * Tags-       , CmdTag(..)-       , TagE-       , Tag((.+),remTag,tagMatch)-       , (.&)-       , (.||)-       , notT-       , externTags-       , dictionaryOfTags-       -- * Boxes-       -- | Boxes are used by the 'Extern' class.-       , TagBox(..)-       , IntBox(..)-       , RewriteCoreBox(..)-       , RewriteCoreTCBox(..)-       , BiRewriteCoreBox(..)-       , TranslateCoreStringBox(..)-       , TranslateCoreTCStringBox(..)-       , TranslateCoreCheckBox(..)-       , NameBox(..)-       , CoreString(..)-       , CoreBox(..)-       , CrumbBox(..)-       , PathBox(..)-       , TranslateCorePathBox(..)-       , StringBox(..)-       , NameListBox(..)-       , StringListBox(..)-) where--import Data.Map hiding (map)-import Data.Dynamic-import Data.List--import qualified Language.Haskell.TH as TH--import Language.HERMIT.Core-import Language.HERMIT.Kure----------------------------------------------------------------------- | 'External' names are just strings.-type ExternalName = String---- | Help information for 'External's is stored as a list of strings, designed for multi-line displaying.-type ExternalHelp = [String]---- Tags ------------------------------------------------------------ | Requirement: commands cannot have the same name as any 'CmdTag'---   (or the help function will not find it).---   These should be /user facing/, because they give the user---   a way of sub-dividing our confusing array of commands.-data CmdTag = Shell          -- ^ Shell-specific command.-            | Eval           -- ^ The arrow of evaluation (reduces a term).-            | KURE           -- ^ 'Language.KURE' command.-            | Loop           -- ^ Command may operate multiple times.-            | Deep           -- ^ Command may make a deep change, can be O(n).-            | Shallow        -- ^ Command operates on local nodes only, O(1).-            | Navigation     -- ^ Uses 'Path' or 'Lens' to focus onto something.-            | Query          -- ^ A question we ask.-            | Predicate      -- ^ Something that passes or fails.-            | Introduce      -- ^ Introduce something, like a new name.-            | Commute        -- ^ Commute is when you swap nested terms.-            | PreCondition   -- ^ Operation has a (perhaps undocumented) precondition.-            | Debug          -- ^ Commands specifically to help debugging.-            | VersionControl -- ^ Version control for Core syntax.-            | Bash           -- ^ Commands that are run by 'Language.HERMIT.Dictionary.bash'.-            | Context        -- ^ A command that uses its context, such as inlining.-            | Unsafe         -- ^ Commands that are not type safe (may cause Core Lint to fail),-                             --   or may otherwise change the semantics of the program.--            | TODO           -- ^ An incomplete or potentially buggy command.-            | Experiment     -- ^ Things we are trying out.-            | Deprecated     -- ^ A command that will be removed in a future release;-                             --   it has probably been renamed or subsumed by another command.----- Unsure about these-{--            | Local         -- local thing, O(1)-            | CaseCmd       -- works on case statements-            | Context       -- something that uses the context-            | GHC           -- a tunnel into GHC-            | Lens          -- focuses into a specific node-            | LetCmd        -- works on let statements-            | Meta          -- combines other commands-            | Restful       -- RESTful API commands-            | Slow          -- this command is slow--}-            -- Other String-            -- etc-    deriving (Eq, Show, Read, Bounded, Enum)---- | Lists all the tags paired with a short description of what they're about.-dictionaryOfTags :: [(CmdTag,String)]-dictionaryOfTags = notes ++ [ (tag,"(unknown purpose)")-                            | tag <- [minBound..maxBound]-                            , tag `notElem` map fst notes-                            ]-  where notes =-          -- These should give the user a clue about what the sub-commands-          -- might do-          [ (Shell,        "Shell-specific command.")-          , (Eval,         "The arrow of evaluation (reduces a term).")-          , (KURE,         "Direct reflection of a combinator from the KURE DSL.")-          , (Loop,         "Command may operate multiple times.")-          , (Deep,         "Command may make a deep change, can be O(n).")-          , (Shallow,      "Command operates on local nodes only, O(1).")-          , (Navigation,   "Navigate via focus, or directional command.")-          , (Query,        "A question we ask.")-          , (Predicate,    "Something that passes or fails.")-          , (Introduce,    "Introduce something, like a new name.")-          , (Commute,      "Commute is when you swap nested terms.")-          , (PreCondition, "Operation has a (perhaps undocumented) precondition.")-          , (Debug,        "A command specifically to help debugging.")-          , (VersionControl,"Version control for Core syntax.")-          , (Bash,         "A command that runs as part of the \"bash\" command.")-          , (Context,      "A command that uses its context, such as inlining.")-          , (Unsafe,       "Commands that are not type safe (may cause Core Lint to fail), or may otherwise change the semantics of the program.")--          , (TODO,         "An incomplete or potentially buggy command.")-          , (Experiment,   "Things we are trying out, use at your own risk.")-          , (Deprecated,   "A command that will be removed in a future release; it has probably been renamed or subsumed by another command.")-          ]----- Unfortunately, record update syntax seems to associate to the right.--- These operators save us some parentheses.-infixl 3 .+-infixr 4 .||-infixr 5 .&---- | A data type of logical operations on tags.-data TagE :: * where-    Tag    :: Tag a => a -> TagE-    NotTag :: TagE -> TagE-    AndTag :: TagE -> TagE -> TagE-    OrTag  :: TagE -> TagE -> TagE---- | Tags are meta-data that we add to 'External's to make them sortable and searchable.-class Tag a where-    toTagE :: a -> TagE--    -- | Add a 'Tag' to an 'External'.-    (.+) :: External -> a -> External--    -- | Remove a 'Tag' from an 'External'.-    remTag :: a -> External -> External--    -- | Check if an 'External' has the specified 'Tag'.-    tagMatch :: a -> External -> Bool--instance Tag TagE where-    toTagE = id--    e .+ (Tag t) = e .+ t-    e .+ (NotTag t) = remTag t e-    e .+ (AndTag t1 t2) = e .+ t1 .+ t2-    e .+ (OrTag t1 t2) = e .+ t1 .+ t2 -- not sure what else to do--    remTag (Tag t) e = remTag t e-    remTag (NotTag t) e = e .+ t-    remTag (AndTag t1 t2) e = remTag t1 (remTag t2 e)-    remTag (OrTag t1 t2) e = remTag t1 (remTag t2 e) -- again--    tagMatch (Tag t)        e = tagMatch t e-    tagMatch (NotTag t)     e = not (tagMatch t e)-    tagMatch (AndTag t1 t2) e = tagMatch t1 e && tagMatch t2 e-    tagMatch (OrTag  t1 t2) e = tagMatch t1 e || tagMatch t2 e--instance Tag CmdTag where-    toTagE = Tag-    ex@(External {externTags = ts}) .+ t = ex {externTags = t:ts}-    remTag t ex@(External {externTags = ts}) = ex { externTags = [ t' | t' <- ts, t' /= t ] }-    tagMatch t (External {externTags = ts}) = t `elem` ts---- | An \"and\" on 'Tag's.-(.&) :: (Tag a, Tag b) => a -> b -> TagE-t1 .& t2 = AndTag (toTagE t1) (toTagE t2)---- | An \"or\" on 'Tag's.-(.||) :: (Tag a, Tag b) => a -> b -> TagE-t1 .|| t2 = OrTag (toTagE t1) (toTagE t2)---- how to make a unary operator?--- | A \"not\" on 'Tag's.-notT :: Tag a => a -> TagE-notT = NotTag . toTagE----------------------------------------------------------------------- | An 'External' is a 'Dynamic' value with some associated meta-data (name, help string and tags).-data External = External-        { externName :: ExternalName        -- ^ Get the name of an 'External'.-        , externFun  :: Dynamic             -- ^ Get the 'Dynamic' value stored in an 'External'.-        , externHelp :: ExternalHelp        -- ^ Get the list of help 'String's for an 'External'.-        , externTags :: [CmdTag]            -- ^ List all the 'CmdTag's associated with an 'External'-        }---- | The primitive way to build an 'External'.-external :: Extern a => ExternalName -> a -> ExternalHelp -> External-external nm fn help = External-        { externName = nm-        , externFun  = toDyn (box fn)-        , externHelp = map ("  " ++) help-        , externTags = []-        }---- | Get all the 'External's which match a given tag predicate--- and box a Translate of the appropriate type.-matchingExternals :: (Extern tr, Tag t) => t -> [External] -> [(External, tr)]-matchingExternals tag exts = [ (e,tr) | e <- exts, tagMatch tag e-                                      , Just tr <- [fmap unbox $ fromDynamic $ externFun e] ]---- | Build a 'Data.Map' from names to 'Dynamic' values.-toDictionary :: [External] -> Map ExternalName [Dynamic]-toDictionary-        -- TODO: check names are uniquely-prefixed-              = fromListWith (++) . map toD-  where-         toD :: External -> (ExternalName,[Dynamic])-         toD e = (externName e,[externFun e])---- | Build a 'Data.Map' from names to help information.-toHelp :: [External] -> Map ExternalName ExternalHelp-toHelp = fromListWith (++) . map toH-  where-         toH :: External -> (ExternalName,ExternalHelp)-         toH e = (externName e, spaceout (externName e ++ " :: " ++ fixup (show (dynTypeRep (externFun e))))-                                         (show (externTags e)) : externHelp e)--         spaceout xs ys = xs ++ replicate (width - (length xs + length ys)) ' ' ++ ys--         width = 78--         fixup :: String -> String-         fixup xs | "Box" `isPrefixOf` xs = fixup (drop 3 xs)-         fixup (x:xs)                     = x : fixup xs-         fixup []                         = []------------------------------------------------------------------------ | The class of things that can be made into 'External's.---   To be an 'Extern' there must exist an isomorphic 'Box' type that is an instance of 'Typeable'.-class Typeable (Box a) => Extern a where--    -- | An isomorphic wrapper.-    type Box a--    -- | Wrap a value in a 'Box'.-    box :: a -> Box a--    -- | Unwrap a value from a 'Box'.-    unbox :: Box a -> a---------------------------------------------------------------------instance (Extern a, Extern b) => Extern (a -> b) where-    type Box (a -> b) = Box a -> Box b-    box f = box . f . unbox-    unbox f = unbox . f . box---------------------------------------------------------------------data TagBox = TagBox TagE deriving Typeable--instance Extern TagE where-    type Box TagE = TagBox-    box = TagBox-    unbox (TagBox t) = t---------------------------------------------------------------------data IntBox = IntBox Int deriving Typeable--instance Extern Int where-    type Box Int = IntBox-    box = IntBox-    unbox (IntBox i) = i---------------------------------------------------------------------data RewriteCoreBox = RewriteCoreBox (RewriteH Core) deriving Typeable--instance Extern (RewriteH Core) where-    type Box (RewriteH Core) = RewriteCoreBox-    box = RewriteCoreBox-    unbox (RewriteCoreBox r) = r---------------------------------------------------------------------data RewriteCoreTCBox = RewriteCoreTCBox (RewriteH CoreTC) deriving Typeable--instance Extern (RewriteH CoreTC) where-    type Box (RewriteH CoreTC) = RewriteCoreTCBox-    box = RewriteCoreTCBox-    unbox (RewriteCoreTCBox r) = r---------------------------------------------------------------------data BiRewriteCoreBox = BiRewriteCoreBox (BiRewriteH Core) deriving Typeable--instance Extern (BiRewriteH Core) where-    type Box (BiRewriteH Core) = BiRewriteCoreBox-    box = BiRewriteCoreBox-    unbox (BiRewriteCoreBox b) = b---------------------------------------------------------------------data TranslateCoreTCStringBox = TranslateCoreTCStringBox (TranslateH CoreTC String) deriving Typeable--instance Extern (TranslateH CoreTC String) where-    type Box (TranslateH CoreTC String) = TranslateCoreTCStringBox-    box = TranslateCoreTCStringBox-    unbox (TranslateCoreTCStringBox t) = t---------------------------------------------------------------------data TranslateCoreStringBox = TranslateCoreStringBox (TranslateH Core String) deriving Typeable--instance Extern (TranslateH Core String) where-    type Box (TranslateH Core String) = TranslateCoreStringBox-    box = TranslateCoreStringBox-    unbox (TranslateCoreStringBox t) = t---------------------------------------------------------------------data TranslateCoreCheckBox = TranslateCoreCheckBox (TranslateH Core ()) deriving Typeable--instance Extern (TranslateH Core ()) where-    type Box (TranslateH Core ()) = TranslateCoreCheckBox-    box = TranslateCoreCheckBox-    unbox (TranslateCoreCheckBox t) = t---------------------------------------------------------------------data NameBox = NameBox (TH.Name) deriving Typeable--instance Extern TH.Name where-    type Box TH.Name = NameBox-    box = NameBox-    unbox (NameBox n) = n----------------------------------------------------------------------- TODO: We now have CrumbBoc, PathBox and TranslateCorePathBox.---       Ints are interpreted as a TranslateCorePathBox.---       This all needs cleaning up.--data CrumbBox = CrumbBox Crumb deriving Typeable--instance Extern Crumb where-    type Box Crumb = CrumbBox-    box = CrumbBox-    unbox (CrumbBox cr) = cr---------------------------------------------------------------------data PathBox = PathBox PathH deriving Typeable--instance Extern PathH where-    type Box PathH = PathBox-    box = PathBox-    unbox (PathBox p) = p---------------------------------------------------------------------data TranslateCorePathBox = TranslateCorePathBox (TranslateH Core PathH) deriving Typeable--instance Extern (TranslateH Core PathH) where-    type Box (TranslateH Core PathH) = TranslateCorePathBox-    box = TranslateCorePathBox-    unbox (TranslateCorePathBox t) = t---------------------------------------------------------------------newtype CoreString = CoreString { unCoreString :: String }-data CoreBox = CoreBox CoreString deriving Typeable--instance Extern CoreString where-    type Box CoreString = CoreBox-    box = CoreBox-    unbox (CoreBox s) = s---------------------------------------------------------------------data StringBox = StringBox String deriving Typeable--instance Extern String where-    type Box String = StringBox-    box = StringBox-    unbox (StringBox s) = s---------------------------------------------------------------------data NameListBox = NameListBox [TH.Name] deriving Typeable--instance Extern [TH.Name] where-    type Box [TH.Name] = NameListBox-    box = NameListBox-    unbox (NameListBox l) = l---------------------------------------------------------------------data StringListBox = StringListBox [String] deriving Typeable--instance Extern [String] where-    type Box [String] = StringListBox-    box = StringListBox-    unbox (StringListBox l) = l-------------------------------------------------------------------
− src/Language/HERMIT/GHC.hs
@@ -1,172 +0,0 @@-{-# LANGUAGE CPP #-}-module Language.HERMIT.GHC-    ( -- * GHC Imports-      -- | Things that have been copied from GHC, or imported directly, for various reasons.-      ppIdInfo-    , var2String-    , thRdrNameGuesses-    , name2THName-    , var2THName-    , cmpTHName2Name-    , cmpString2Name-    , cmpTHName2Var-    , cmpString2Var-    , fqName-    , uqName-    , findNamesFromString-    , findNamesFromTH-    , alphaTyVars-    , Type(..)-    , TyLit(..)-    , GhcException(..)-    , throwGhcException-    , exprArity-    , Language.HERMIT.GHC.coAxiomName-#if __GLASGOW_HASKELL__ > 706-    , CoAxiom.BranchIndex-    , CoAxiom.CoAxiom-    , CoAxiom.Branched-#endif-    ) where--import GhcPlugins as GHC---- hacky direct GHC imports-import Convert (thRdrNameGuesses)-import TysPrim (alphaTyVars)-import TypeRep (Type(..),TyLit(..))-import Panic (GhcException(ProgramError), throwGhcException)-import CoreArity--#if __GLASGOW_HASKELL__ <= 706-import Data.Maybe (isJust)-#else-import qualified CoAxiom -- for coAxiomName-#endif-import qualified Language.Haskell.TH as TH-import Language.Haskell.TH.Syntax (showName)------------------------------------------------------------------------------#if __GLASGOW_HASKELL__ <= 706-coAxiomName :: CoAxiom -> Name-coAxiomName = GHC.coAxiomName-#else-coAxiomName :: CoAxiom.CoAxiom br -> Name-coAxiomName = CoAxiom.coAxiomName-#endif---- varName :: Var -> Name--- nameOccName :: Name -> OccName--- occNameString :: OccName -> String--- getOccName :: NamedThing a => a -> OccName--- getName :: NamedThing a => a -> Name--- getOccString :: NamedThing a => a -> String---- TH.nameBase :: TH.Name -> String--- showName :: TH.Name -> String--- TH.mkName :: String -> TH.Name---- | Get the unqualified name from a 'Name'.-uqName :: Name -> String-uqName = getOccString -- equivalent to: occNameString . getOccName---- | Get the fully qualified name from a 'Name'.-fqName :: Name -> String-fqName nm = modStr ++ uqName nm-    where modStr = maybe "" (\m -> moduleNameString (moduleName m) ++ ".") (nameModule_maybe nm)---- | Convert a variable to a neat string for printing (unqualfied name).-var2String :: Var -> String-var2String = uqName . varName---- | Converts a GHC 'Name' to a Template Haskell 'TH.Name', going via a 'String'.-name2THName :: Name -> TH.Name-name2THName = TH.mkName . uqName---- | Converts an 'Var' to a Template Haskell 'TH.Name', going via a 'String'.-var2THName :: Var -> TH.Name-var2THName = name2THName . varName---- | Compare a 'String' to a 'Name' for equality.--- Strings containing a period are assumed to be fully qualified names.-cmpString2Name :: String -> Name -> Bool-cmpString2Name str nm | isQualified str = str == fqName nm-                      | otherwise       = str == uqName nm--isQualified :: String -> Bool-isQualified [] = False-isQualified xs = '.' `elem` init xs -- pathological case is compose---- | Compare a 'String' to a 'Var' for equality. See 'cmpString2Name'.-cmpString2Var :: String -> Var -> Bool-cmpString2Var str = cmpString2Name str . varName---- | Compare a 'TH.Name' to a 'Name' for equality. See 'cmpString2Name'.-cmpTHName2Name :: TH.Name -> Name -> Bool-cmpTHName2Name th_nm = cmpString2Name (showName th_nm)---- | Compare a 'TH.Name' to a 'Var' for equality. See 'cmpString2Name'.-cmpTHName2Var :: TH.Name -> Var -> Bool-cmpTHName2Var nm = cmpTHName2Name nm . varName---- | Find 'Name's matching a given fully qualified or unqualified name.--- If given name is fully qualified, will only return first result, which is assumed unique.-findNamesFromString :: GlobalRdrEnv -> String -> [Name]-findNamesFromString rdrEnv str | isQualified str = take 1 res-                               | otherwise       = res-    where res = [ nm | elt <- globalRdrEnvElts rdrEnv, let nm = gre_name elt, cmpString2Name str nm ]---- | Find 'Name's matching a 'TH.Name'. See 'findNamesFromString'.-findNamesFromTH :: GlobalRdrEnv -> TH.Name -> [Name]-findNamesFromTH rdrEnv = findNamesFromString rdrEnv . showName---- | Pretty-print an identifier.-ppIdInfo :: Id -> IdInfo -> SDoc-ppIdInfo v info-  = showAttributes-    [ (True, pp_scope <> ppr (idDetails v))-    , (has_arity,      ptext (sLit "Arity=") <> int arity)-    , (has_caf_info,   ptext (sLit "Caf=") <> ppr caf_info)-    , (has_strictness, ptext (sLit "Str=") <> pprStrictness str_info)-    , (has_unf,        ptext (sLit "Unf=") <> ppr unf_info)-    , (not (null rules), ptext (sLit "RULES:") <+> vcat (map ppr rules))-    ]	-- Inline pragma, occ, demand, lbvar info-	-- printed out with all binders (when debug is on);-	-- see PprCore.pprIdBndr-  where-    pp_scope | isGlobalId v   = ptext (sLit "GblId")-    	     | isExportedId v = ptext (sLit "LclIdX")-    	     | otherwise      = ptext (sLit "LclId")--    arity = arityInfo info-    has_arity = arity /= 0--    caf_info = cafInfo info-    has_caf_info = not (mayHaveCafRefs caf_info)--    str_info = strictnessInfo info-    has_strictness =-#if __GLASGOW_HASKELL__ > 706-        True-#else-        isJust str_info-#endif--    unf_info = unfoldingInfo info-    has_unf = hasSomeUnfolding unf_info--    rules = specInfoRules (specInfo info)--showAttributes :: [(Bool,SDoc)] -> SDoc-showAttributes stuff-  | null docs = empty-  | otherwise = brackets (sep (punctuate comma docs))-  where-    docs = [d | (True,d) <- stuff]--------------------------------------------------------------------------------
− src/Language/HERMIT/Interp.hs
@@ -1,88 +0,0 @@-{-# LANGUAGE KindSignatures, GADTs, InstanceSigs #-}--module Language.HERMIT.Interp-        ( -- * The HERMIT Interpreter-          Interp-        , interp-        , interpExprH-        ) where--import Control.Monad (liftM, liftM2)--import Data.Char-import Data.Dynamic-import qualified Data.Map as M--import qualified Language.Haskell.TH as TH--import Language.HERMIT.External-import Language.HERMIT.Parser-import Language.HERMIT.Kure (deprecatedIntToPathT)---- | Interpret an 'ExprH' by looking up the appropriate 'Dynamic'(s) in the provided 'Data.Map', then interpreting the 'Dynamic'(s) with the provided 'Interp's, returning the first interpretation to succeed (or an error string if none succeed).-interpExprH :: M.Map String [Dynamic] -> [Interp a] -> ExprH -> Either String a-interpExprH env interps =-          either Left (\ dyns -> runInterp dyns (map (fmap Right) interps) (Left "User error, HERMIT command does not type-check."))-          . interpExpr env--runInterp :: [Dynamic] -> [Interp b] -> b -> b-runInterp dyns interps bad = head $-             [f a-             | Interp f <- interps-             , Just a <- map fromDynamic dyns-             ] ++ [ bad ]---- | An 'Interp' @a@ is a /possible/ means of converting a 'Typeable' value to a value of type @a@.-data Interp :: * -> * where-   Interp :: Typeable a => (a -> b) -> Interp b---- | The primitive way of building an 'Interp'.-interp :: Typeable a => (a -> b) -> Interp b-interp = Interp--instance Functor Interp where-  fmap :: (a -> b) -> Interp a -> Interp b-  fmap f (Interp g) = Interp (f . g)---interpExpr :: M.Map String [Dynamic] -> ExprH -> Either String [Dynamic]-interpExpr = interpExpr' False---- input: list length n, each elem is a variable length list of possible interpretations--- output: variable length list, each elem is list of length n-fromDynList :: [[Dynamic]] -> [[Dynamic]]-fromDynList [] = [[]]-fromDynList (hs:dynss) = [ h:t | h <- hs, t <- fromDynList dynss ]--toBoxedList :: (Extern a, Typeable b) => [[Dynamic]] -> ([a] -> b) -> [Dynamic]-toBoxedList dyns boxCon = [ toDyn $ boxCon (map unbox l) | dl <- dyns, Just l <- [mapM fromDynamic dl] ]--interpExpr' :: Bool -> M.Map String [Dynamic] -> ExprH -> Either String [Dynamic]-interpExpr' _   _   (SrcName str) = return [ toDyn $ NameBox $ TH.mkName str ]-interpExpr' _   _   (CoreH str)   = return [ toDyn $ CoreBox (CoreString str) ]-interpExpr' _   env (ListH exprs) = do dyns <- liftM fromDynList $ mapM (interpExpr' True env) exprs-                                       return $    toBoxedList dyns NameListBox-                                                ++ toBoxedList dyns StringListBox-                                                ++ toBoxedList dyns PathBox-interpExpr' rhs env (CmdName str)-                                        -- An Int is either a Path, or will be interpreted specially later.-  | all isDigit str                     = let i = read str in-                                          return [ toDyn $ IntBox i-                                                 , toDyn $ TranslateCorePathBox (deprecatedIntToPathT i) -- TODO: Find a better long-term solution.-                                                 ]-  | Just dyn <- M.lookup str env        = return $ if rhs-                                                     then toDyn (StringBox str) : dyn-                                                     else dyn-  -- not a command, try as a string arg... worst case: dynApply fails with "bad type of expression"-  -- best case: 'help ls' works instead of 'help "ls"'. this is likewise done in the clause above-  | rhs                                 = return [toDyn $ StringBox str]-  | otherwise                           = Left $ "User error, unrecognised HERMIT command: " ++ show str-interpExpr' _ env (AppH e1 e2)              = dynAppMsg (interpExpr' False env e1) (interpExpr' True env e2)--dynAppMsg :: Either String [Dynamic] -> Either String [Dynamic] -> Either String [Dynamic]-dynAppMsg = liftM2 dynApply'-   where-           dynApply' :: [Dynamic] -> [Dynamic] -> [Dynamic]-           dynApply' fs xs = [ r | f <- fs, x <- xs, Just r <- return (dynApply f x)]---------------------------------------------
− src/Language/HERMIT/Kernel.hs
@@ -1,122 +0,0 @@-{-# LANGUAGE GADTs, RankNTypes, ScopedTypeVariables, DeriveDataTypeable, TupleSections #-}--module Language.HERMIT.Kernel-        ( -- * The HERMIT Kernel-          AST-        , Kernel-        , hermitKernel-        , resumeK-        , abortK-        , applyK-        , queryK-        , deleteK-        , listK-) where--import Prelude hiding (lookup)--import GhcPlugins hiding (singleton, empty)--import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.GHC--import Data.Map-import Control.Concurrent---- | A 'Kernel' is a repository for complete Core syntax trees ('ModGuts').---   For now, operations on a 'Kernel' are sequential, but later---   it will be possible to have two 'applyK's running in parallel.-data Kernel = Kernel-  { resumeK ::            AST                                        -> IO ()           -- ^ Halt the 'Kernel' and return control to GHC, which compiles the specified 'AST'.-  , abortK  ::                                                          IO ()           -- ^ Halt the 'Kernel' and abort GHC without compiling.-  , applyK  ::            AST -> RewriteH ModGuts     -> HermitMEnv  -> IO (KureM AST)  -- ^ Apply a 'Rewrite' to the specified 'AST' and return a handle to the resulting 'AST'.-  , queryK  :: forall a . AST -> TranslateH ModGuts a -> HermitMEnv  -> IO (KureM a)    -- ^ Apply a 'TranslateH' to the 'AST' and return the resulting value.-  , deleteK ::            AST                                        -> IO ()           -- ^ Delete the internal record of the specified 'AST'.-  , listK   ::                                                          IO [AST]        -- ^ List all the 'AST's tracked by the 'Kernel'.-  }---- | A /handle/ for a specific version of the 'ModGuts'.-newtype AST = AST Int -- ^ Currently 'AST's are identified by an 'Int' label.-              deriving (Eq, Ord, Show)--data Msg s r = forall a . Req (s -> CoreM (KureM (a,s))) (MVar (KureM a))-             | Done (s -> CoreM r)--type KernelState = Map AST (DefStash, ModGuts)---- | Start a HERMIT client by providing an IO function that takes the initial 'Kernel' and inital 'AST' handle.---   The 'Modguts' to 'CoreM' Modguts' function required by GHC Plugins is returned.---   The callback is only ever called once.-hermitKernel :: (Kernel -> AST -> IO ()) -> ModGuts -> CoreM ModGuts-hermitKernel callback modGuts = do--        msgMV :: MVar (Msg KernelState ModGuts) <- liftIO newEmptyMVar--        nextASTname :: MVar AST <- liftIO newEmptyMVar--        _ <- liftIO $ forkIO $ let loop n = do putMVar nextASTname (AST n)-                                               loop (succ n)-                                in loop 0--        let sendDone :: (KernelState -> CoreM ModGuts) -> IO ()-            sendDone = putMVar msgMV . Done--        let sendReq :: (KernelState -> CoreM (KureM (a, KernelState))) -> IO (KureM a)-            sendReq fn = do rep  <- newEmptyMVar-                            putMVar msgMV (Req fn rep)-                            takeMVar rep--        let sendReqRead :: (KernelState -> CoreM (KureM a)) -> IO (KureM a)-            sendReqRead fn = sendReq (\ st -> (fmap.fmap) (,st) $ fn st)--        let sendReqWrite :: (KernelState -> CoreM KernelState) -> IO ()-            sendReqWrite fn = sendReq (fmap ( return . ((),) ) . fn) >>= runKureM return fail--        let kernel :: Kernel-            kernel = Kernel-                { resumeK = \ name -> sendDone $ \ st -> findWithErrMsg name st (\ msg -> throwGhcException $ ProgramError $ msg ++ ", exiting HERMIT and aborting GHC compilation.") (return.snd)--                , abortK  = sendDone $ \ _ -> throwGhcException (ProgramError "Exiting HERMIT and aborting GHC compilation.")--                , applyK = \ name r hm_env -> sendReq $ \ st -> findWithErrMsg name st fail $ \ (defs, guts) -> runHM hm_env-                                                                                                               defs-                                                                                                               (\ defs' guts' -> do ast <- liftIO $ takeMVar nextASTname-                                                                                                                                    return $ return (ast, insert ast (defs',guts') st))-                                                                                                               (return . fail)-                                                                                                               (apply r (initHermitC guts) guts)--                , queryK = \ name t hm_env -> sendReqRead $ \ st -> findWithErrMsg name st fail $ \ (defs, core) -> runHM hm_env-                                                                                                                      defs-                                                                                                                      (\ _ -> return.return)-                                                                                                                      (return . fail)-                                                                                                                      (apply t (initHermitC core) core)--                , deleteK = \ name -> sendReqWrite (return . delete name)--                , listK = sendReqRead (return . return . keys) >>= runKureM return fail-                }--        -- We always start with AST 0-        ast0 <- liftIO $ takeMVar nextASTname--        let loop :: KernelState -> CoreM ModGuts-            loop st = do-                m <- liftIO $ takeMVar msgMV-                case m of-                  Req fn rep -> fn st >>= runKureM (\ (a,st') -> liftIO (putMVar rep $ return a) >> loop st')-                                                   (\ msg     -> liftIO (putMVar rep $ fail msg) >> loop st)-                  Done fn -> fn st--        _pid <- liftIO $ forkIO $ callback kernel ast0--        loop (singleton ast0 (empty, modGuts))--        -- (Kill the pid'd thread? do we need to?)--findWithErrMsg :: AST -> Map AST v -> (String -> b) -> (v -> b) -> b-findWithErrMsg ast m f = find ast m (f $ "Cannot find syntax tree: " ++ show ast)--find :: Ord k => k -> Map k v -> b -> (v -> b) -> b-find k m f s = maybe f s (lookup k m)
− src/Language/HERMIT/Kernel/Scoped.hs
@@ -1,183 +0,0 @@-{-# LANGUAGE RankNTypes, FlexibleContexts #-}-module Language.HERMIT.Kernel.Scoped-       (-         Direction(..)-       , LocalPath-       , moveLocally-       , extendLocalPath-       , ScopedKernel(..)-       , SAST(..)-       , scopedKernel-) where---import Control.Arrow-import Control.Concurrent.STM-import Control.Exception (bracketOnError, catch, SomeException)--import Data.Maybe (fromMaybe)-import Data.Monoid (mempty)-import qualified Data.IntMap as I--import GhcPlugins hiding (Direction,L)--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.Monad-import Language.HERMIT.Kernel---------------------------------------------------------------------------------- | A primitive means of denoting navigation of a tree (within a local scope).-data Direction = L -- ^ Left-               | R -- ^ Right-               | U -- ^ Up-               | T -- ^ Top-               deriving (Eq,Show)---- | The path within the current local scope.-type LocalPath = SnocPath-type LocalPathH = LocalPath Crumb--pathStack2Paths :: [LocalPath crumb] -> LocalPath crumb -> [Path crumb]-pathStack2Paths ps p = reverse (map snocPathToPath (p:ps))---- | Add a 'Path' to the end of a 'LocalPath'.-extendLocalPath :: Path crumb -> LocalPath crumb -> LocalPath crumb-extendLocalPath p (SnocPath sp) = SnocPath (reverse p ++ sp)-{-# INLINE extendLocalPath #-}---- | Movement confined within the local scope.-moveLocally :: Direction -> LocalPathH -> LocalPathH-moveLocally d (SnocPath p) = case p of-                               []     -> mempty-                               cr:crs -> case d of-                                           T -> mempty-                                           U -> SnocPath crs-                                           L -> SnocPath (fromMaybe cr (deprecatedLeftSibling cr)  : crs)-                                           R -> SnocPath (fromMaybe cr (deprecatedRightSibling cr) : crs)---pathStackToLens :: (Injection ModGuts g, Walker HermitC g) => [LocalPathH] -> LocalPathH -> LensH ModGuts g-pathStackToLens ps p = injectL >>> pathL (concat $ pathStack2Paths ps p)---- This function is used to check the validity of paths, so which sum type we use is important.-testPathStackT :: [LocalPathH] -> LocalPathH -> TranslateH ModGuts Bool-testPathStackT ps p = testLensT (pathStackToLens ps p :: LensH ModGuts CoreTC)---------------------------------------------------------------------------------- | An alternative HERMIT kernel, that provides scoping.-data ScopedKernel = ScopedKernel-  { resumeS      ::            SAST                                              -> IO (KureM ())-  , abortS       ::                                                                 IO ()-  , applyS       :: forall g. (Injection ModGuts g, Walker HermitC g) =>-                               SAST -> RewriteH g                  -> HermitMEnv -> IO (KureM SAST)-  , queryS       :: forall a g . (Injection ModGuts g, Walker HermitC g) =>-                               SAST -> TranslateH g a              -> HermitMEnv -> IO (KureM a)-  , deleteS      ::            SAST                                              -> IO (KureM ())-  , listS        ::                                                                 IO [SAST]-  , pathS        ::            SAST                                              -> IO (KureM [PathH])-  , modPathS     ::            SAST -> (LocalPathH -> LocalPathH)  -> HermitMEnv -> IO (KureM SAST)-  , beginScopeS  ::            SAST                                              -> IO (KureM SAST)-  , endScopeS    ::            SAST                                              -> IO (KureM SAST)-  -- means of accessing the underlying kernel, obviously for unsafe purposes-  , kernelS      ::                                                                 Kernel-  , toASTS       ::            SAST                                              -> IO (KureM AST)-  }---- | A /handle/ for an 'AST' combined with scoping information.-newtype SAST = SAST Int deriving (Eq, Ord, Show)---- path stack, representing the base path, then the relative path-type SASTStore = I.IntMap (AST, [LocalPathH], LocalPathH)--get :: Monad m => Int -> SASTStore -> m (AST, [LocalPathH], LocalPathH)-get sAst m = maybe (fail "scopedKernel: invalid SAST") return (I.lookup sAst m)---- | Ensures that the TMVar is replaced when an error is thrown, and all exceptions are lifted into KureM failures.-safeTakeTMVar :: TMVar a -> (a -> IO b) -> IO (KureM b)-safeTakeTMVar mvar = catchFails . bracketOnError (atomically $ takeTMVar mvar) (atomically . putTMVar mvar)---- | Lifts exceptions into KureM failures.-catchFails :: IO a -> IO (KureM a)-catchFails io = (io >>= (return.return)) `catch` (\e -> return $ fail $ show (e :: SomeException))---- | Start a HERMIT client by providing an IO function that takes the initial 'ScopedKernel' and inital 'SAST' handle.---   The 'Modguts' to 'CoreM' Modguts' function required by GHC Plugins is returned.-scopedKernel :: (ScopedKernel -> SAST -> IO ()) -> ModGuts -> CoreM ModGuts-scopedKernel callback = hermitKernel $ \ kernel initAST -> do-    store <- newTMVarIO $ I.fromList [(0,(initAST, [], mempty))]-    key <- newTMVarIO (1::Int)--    let newKey = do-            k <- takeTMVar key-            putTMVar key (k+1)-            return k--        skernel = ScopedKernel-            { resumeS     = \ (SAST sAst) -> catchFails $ do-                                m <- atomically $ readTMVar store-                                (ast,_,_) <- get sAst m-                                resumeK kernel ast-            , abortS      = abortK kernel-            , applyS      = \ (SAST sAst) rr env -> safeTakeTMVar store $ \ m -> do-                                (ast, base, rel) <- get sAst m-                                applyK kernel ast (focusR (pathStackToLens base rel) rr) env-                                  >>= runKureM (\ ast' -> atomically $ do k <- newKey-                                                                          putTMVar store $ I.insert k (ast', base, rel) m-                                                                          return $ SAST k)-                                               fail-            , queryS      = \ (SAST sAst) t env -> catchFails $ do-                                m <- atomically $ readTMVar store-                                (ast, base, rel) <- get sAst m-                                queryK kernel ast (focusT (pathStackToLens base rel) t) env-                                    >>= runKureM return fail-            , deleteS     = \ (SAST sAst) -> safeTakeTMVar store $ \ m -> do-                                (ast,_,_) <- get sAst m-                                let m' = I.delete sAst m-                                    fst3 (x,_,_) = x-                                    asts = I.foldr ((:) . fst3) [] m'-                                if ast `elem` asts-                                    then return ()-                                    else deleteK kernel ast-                                atomically $ putTMVar store m'-            , listS       = do m <- atomically $ readTMVar store-                               return [ SAST sAst | sAst <- I.keys m ]-            , pathS       = \ (SAST sAst) -> catchFails $ do-                                m <- atomically $ readTMVar store-                                (_, base, rel) <- get sAst m-                                return $ pathStack2Paths base rel-            , modPathS    = \ (SAST sAst) f env -> safeTakeTMVar store $ \ m -> do-                                (ast, base, rel) <- get sAst m-                                let rel' = f rel-                                queryK kernel ast (testPathStackT base rel') env-                                  >>= runKureM (\ b -> if rel == rel'-                                                        then fail "Path is unchanged, nothing to do."-                                                        else if b-                                                              then atomically $ do k <- newKey-                                                                                   putTMVar store $ I.insert k (ast, base, rel') m-                                                                                   return $ SAST k-                                                              else fail "Invalid path created.")-                                               fail-            , beginScopeS = \ (SAST sAst) -> safeTakeTMVar store $ \m -> do-                                (ast, base, rel) <- get sAst m-                                atomically $ do k <- newKey-                                                putTMVar store $ I.insert k (ast, rel : base, mempty) m-                                                return $ SAST k-            , endScopeS   = \ (SAST sAst) -> safeTakeTMVar store $ \m -> do-                                (ast, base, _) <- get sAst m-                                case base of-                                    []          -> fail "Scoped Kernel: no scope to end."-                                    rel : base' -> atomically $ do k <- newKey-                                                                   putTMVar store $ I.insert k (ast, base', rel) m-                                                                   return $ SAST k-            , kernelS     = kernel-            , toASTS      = \ (SAST sAst) -> catchFails $ do-                                m <- atomically $ readTMVar store-                                (ast, _, _) <- get sAst m-                                return ast-            }--    callback skernel $ SAST 0
− src/Language/HERMIT/Kure.hs
@@ -1,1358 +0,0 @@-{-# LANGUAGE CPP, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances, TupleSections, LambdaCase, InstanceSigs, ScopedTypeVariables #-}--module Language.HERMIT.Kure-       (-       -- * KURE--       -- | All the required functionality of KURE is exported here, so other modules do not need to import KURE directly.-         module Language.KURE-       , module Language.KURE.BiTranslate-       , module Language.KURE.Lens-       -- * Sub-Modules-       , module Language.HERMIT.Kure.SumTypes-       -- * Synonyms-       , TranslateH-       , RewriteH-       , BiRewriteH-       , LensH-       , PathH--       -- * Congruence combinators-       -- ** Modguts-       , modGutsT, modGutsR-       -- ** Program-       , progNilT-       , progConsT, progConsAllR, progConsAnyR, progConsOneR-       -- ** Binding Groups-       , nonRecT, nonRecAllR, nonRecAnyR, nonRecOneR-       , recT, recAllR, recAnyR, recOneR-       -- ** Recursive Definitions-       , defT, defAllR, defAnyR, defOneR-       -- ** Case Alternatives-       , altT, altAllR, altAnyR, altOneR-       -- ** Expressions-       , varT, varR-       , litT, litR-       , appT, appAllR, appAnyR, appOneR-       , lamT, lamAllR, lamAnyR, lamOneR-       , letT, letAllR, letAnyR, letOneR-       , caseT, caseAllR, caseAnyR, caseOneR-       , castT, castAllR, castAnyR, castOneR-       , tickT, tickAllR, tickAnyR, tickOneR-       , typeT, typeR-       , coercionT, coercionR-       -- ** Composite Congruence Combinators-       , recDefT, recDefAllR, recDefAnyR, recDefOneR-       , letNonRecT, letNonRecAllR, letNonRecAnyR, letNonRecOneR-       , letRecT, letRecAllR, letRecAnyR, letRecOneR-       , letRecDefT, letRecDefAllR, letRecDefAnyR, letRecDefOneR-       , consNonRecT, consNonRecAllR, consNonRecAnyR, consNonRecOneR-       , consRecT, consRecAllR, consRecAnyR, consRecOneR-       , consRecDefT, consRecDefAllR, consRecDefAnyR, consRecDefOneR-       , caseAltT, caseAltAllR, caseAltAnyR, caseAltOneR-       -- ** Types-       , tyVarT, tyVarR-       , litTyT, litTyR-       , appTyT, appTyAllR, appTyAnyR, appTyOneR-       , funTyT, funTyAllR, funTyAnyR, funTyOneR-       , forAllTyT, forAllTyAllR, forAllTyAnyR, forAllTyOneR-       , tyConAppT, tyConAppAllR, tyConAppAnyR, tyConAppOneR-       -- ** Coercions-       , reflT, reflR-       , tyConAppCoT, tyConAppCoAllR, tyConAppCoAnyR, tyConAppCoOneR-       , appCoT, appCoAllR, appCoAnyR, appCoOneR-       , forAllCoT, forAllCoAllR, forAllCoAnyR, forAllCoOneR-       , coVarCoT, coVarCoR-       , axiomInstCoT, axiomInstCoAllR, axiomInstCoAnyR, axiomInstCoOneR-       , unsafeCoT, unsafeCoAllR, unsafeCoAnyR, unsafeCoOneR-       , symCoT, symCoR-       , transCoT, transCoAllR, transCoAnyR, transCoOneR-       , nthCoT, nthCoAllR, nthCoAnyR, nthCoOneR-       , instCoT, instCoAllR, instCoAnyR, instCoOneR-#if __GLASGOW_HASKELL__ > 706-       , lrCoT, lrCoAllR, lrCoAnyR, lrCoOneR-#else-#endif-       -- * Promotion Combinators-       -- ** Rewrite Promotions-       , promoteModGutsR-       , promoteProgR-       , promoteBindR-       , promoteDefR-       , promoteExprR-       , promoteAltR-       -- ** BiRewrite Promotions-       , promoteExprBiR-       -- ** Translate Promotions-       , promoteModGutsT-       , promoteProgT-       , promoteBindT-       , promoteDefT-       , promoteExprT-       , promoteAltT-       -- * Conversion to deprecated Int representation-       , deprecatedIntToCrumbT-       , deprecatedIntToPathT-       )-where--import GhcPlugins hiding (empty)--import Language.KURE-import Language.KURE.BiTranslate-import Language.KURE.Lens--import Language.HERMIT.Context-import Language.HERMIT.Core-import Language.HERMIT.GHC-import Language.HERMIT.Monad-import Language.HERMIT.Kure.SumTypes--import Control.Monad-------------------------------------------------------------------------type TranslateH a b = Translate HermitC HermitM a b-type RewriteH a     = Rewrite   HermitC HermitM a-type BiRewriteH a   = BiRewrite HermitC HermitM a-type LensH a b      = Lens      HermitC HermitM a b-type PathH          = Path Crumb---- I find it annoying that Applicative is not a superclass of Monad.-(<$>) :: Monad m => (a -> b) -> m a -> m b-(<$>) = liftM-{-# INLINE (<$>) #-}--(<*>) :: Monad m => m (a -> b) -> m a -> m b-(<*>) = ap-{-# INLINE (<*>) #-}--------------------------------------------------------------------------- | Walking over modules, programs, binding groups, definitions, expressions and case alternatives.-instance (ExtendPath c Crumb, AddBindings c) => Walker c Core where--  allR :: forall m. MonadCatch m => Rewrite c m Core -> Rewrite c m Core-  allR r = prefixFailMsg "allR failed: " $-           rewrite $ \ c -> \case-             GutsCore guts  -> inject <$> apply allRmodguts c guts-             ProgCore p     -> inject <$> apply allRprog c p-             BindCore bn    -> inject <$> apply allRbind c bn-             DefCore def    -> inject <$> apply allRdef c def-             AltCore alt    -> inject <$> apply allRalt c alt-             ExprCore e     -> inject <$> apply allRexpr c e-    where-      allRmodguts :: MonadCatch m => Rewrite c m ModGuts-      allRmodguts = modGutsR (extractR r)-      {-# INLINE allRmodguts #-}--      allRprog :: MonadCatch m => Rewrite c m CoreProg-      allRprog = readerT $ \case-                              ProgCons{}  -> progConsAllR (extractR r) (extractR r)-                              _           -> idR-      {-# INLINE allRprog #-}--      allRbind :: MonadCatch m => Rewrite c m CoreBind-      allRbind = readerT $ \case-                              NonRec{}  -> nonRecAllR idR (extractR r) -- we don't descend into the Var-                              Rec _     -> recAllR (const $ extractR r)-      {-# INLINE allRbind #-}--      allRdef :: MonadCatch m => Rewrite c m CoreDef-      allRdef = defAllR idR (extractR r) -- we don't descend into the Id-      {-# INLINE allRdef #-}--      allRalt :: MonadCatch m => Rewrite c m CoreAlt-      allRalt = altAllR idR (const idR) (extractR r) -- we don't descend into the AltCon or Vars-      {-# INLINE allRalt #-}--      allRexpr :: MonadCatch m => Rewrite c m CoreExpr-      allRexpr = readerT $ \case-                              App{}   -> appAllR (extractR r) (extractR r)-                              Lam{}   -> lamAllR idR (extractR r) -- we don't descend into the Var-                              Let{}   -> letAllR (extractR r) (extractR r)-                              Case{}  -> caseAllR (extractR r) idR idR (const $ extractR r) -- we don't descend into the case binder or Type-                              Cast{}  -> castAllR (extractR r) idR -- we don't descend into the Coercion-                              Tick{}  -> tickAllR idR (extractR r) -- we don't descend into the Tickish-                              _       -> idR-      {-# INLINE allRexpr #-}---- NOTE: I tried telling GHC to inline allR and compilation hit the (default) simplifier tick limit.--- TODO: Investigate whether that was achieving useful optimisations.--------------------------------------------------------------------------- | Walking over types (only).-instance (ExtendPath c Crumb, AddBindings c) => Walker c Type where--  allR :: MonadCatch m => Rewrite c m Type -> Rewrite c m Type-  allR r = prefixFailMsg "allR failed: " $-           readerT $ \case-                        AppTy{}     -> appTyAllR r r-                        FunTy{}     -> funTyAllR r r-                        ForAllTy{}  -> forAllTyAllR idR r-                        TyConApp{}  -> tyConAppAllR idR (const r)-                        _           -> idR--------------------------------------------------------------------------- | Walking over coercions (only).-instance (ExtendPath c Crumb, AddBindings c) => Walker c Coercion where--  allR :: MonadCatch m => Rewrite c m Coercion -> Rewrite c m Coercion-  allR r = prefixFailMsg "allR failed: " $-           readerT $ \case-                        TyConAppCo{}  -> tyConAppCoAllR idR (const r)-                        AppCo{}       -> appCoAllR r r-                        ForAllCo{}    -> forAllCoAllR idR r-                        SymCo{}       -> symCoR r-                        TransCo{}     -> transCoAllR r r-                        NthCo{}       -> nthCoAllR idR r-                        InstCo{}      -> instCoAllR r idR-#if __GLASGOW_HASKELL__ > 706-                        LRCo{}        -> lrCoAllR idR r-                        AxiomInstCo{} -> axiomInstCoAllR idR idR (const r)-#else-                        AxiomInstCo{} -> axiomInstCoAllR idR (const r)-#endif-                        _             -> idR--------------------------------------------------------------------------- | Walking over types and coercions.-instance (ExtendPath c Crumb, AddBindings c) => Walker c TyCo where--  allR :: forall m. MonadCatch m => Rewrite c m TyCo -> Rewrite c m TyCo-  allR r = prefixFailMsg "allR failed: " $-           rewrite $ \ c -> \case-             TypeCore ty     -> inject <$> apply (allR $ extractR r) c ty -- exploiting the fact that types do not contain coercions-             CoercionCore co -> inject <$> apply allRcoercion c co-    where-      allRcoercion :: MonadCatch m => Rewrite c m Coercion-      allRcoercion = readerT $ \case-                              Refl{}        -> reflR (extractR r)-                              TyConAppCo{}  -> tyConAppCoAllR idR (const $ extractR r) -- we don't descend into the TyCon-                              AppCo{}       -> appCoAllR (extractR r) (extractR r)-                              ForAllCo{}    -> forAllCoAllR idR (extractR r) -- we don't descend into the TyVar-                              UnsafeCo{}    -> unsafeCoAllR (extractR r) (extractR r)-                              SymCo{}       -> symCoR (extractR r)-                              TransCo{}     -> transCoAllR (extractR r) (extractR r)-                              InstCo{}      -> instCoAllR (extractR r) (extractR r)-                              NthCo{}       -> nthCoAllR idR (extractR r) -- we don't descend into the Int-#if __GLASGOW_HASKELL__ > 706-                              LRCo{}        -> lrCoAllR idR (extractR r)-                              AxiomInstCo{} -> axiomInstCoAllR idR idR (const $ extractR r) -- we don't descend into the axiom or index-#else-                              AxiomInstCo{} -> axiomInstCoAllR idR (const $ extractR r) -- we don't descend into the axiom-#endif-                              _             -> idR-      {-# INLINE allRcoercion #-}--------------------------------------------------------------------------- | Walking over modules, programs, binding groups, definitions, expressions and case alternatives.-instance (ExtendPath c Crumb, AddBindings c) => Walker c CoreTC where--  allR :: forall m. MonadCatch m => Rewrite c m CoreTC -> Rewrite c m CoreTC-  allR r = prefixFailMsg "allR failed: " $-           rewrite $ \ c -> \case-             Core (GutsCore guts)  -> inject <$> apply allRmodguts c guts-             Core (ProgCore p)     -> inject <$> apply allRprog c p-             Core (BindCore bn)    -> inject <$> apply allRbind c bn-             Core (DefCore def)    -> inject <$> apply allRdef c def-             Core (AltCore alt)    -> inject <$> apply allRalt c alt-             Core (ExprCore e)     -> inject <$> apply allRexpr c e-             TyCo tyCo             -> inject <$> apply (allR $ extractR r) c tyCo -- exploiting the fact that only types and coercions appear within types and coercions-    where-      allRmodguts :: MonadCatch m => Rewrite c m ModGuts-      allRmodguts = modGutsR (extractR r)-      {-# INLINE allRmodguts #-}--      allRprog :: MonadCatch m => Rewrite c m CoreProg-      allRprog = readerT $ \case-                              ProgCons{}  -> progConsAllR (extractR r) (extractR r)-                              _           -> idR-      {-# INLINE allRprog #-}--      allRbind :: MonadCatch m => Rewrite c m CoreBind-      allRbind = readerT $ \case-                              NonRec{}  -> nonRecAllR idR (extractR r) -- we don't descend into the Var-                              Rec _     -> recAllR (const $ extractR r)-      {-# INLINE allRbind #-}--      allRdef :: MonadCatch m => Rewrite c m CoreDef-      allRdef = defAllR idR (extractR r) -- we don't descend into the Id-      {-# INLINE allRdef #-}--      allRalt :: MonadCatch m => Rewrite c m CoreAlt-      allRalt = altAllR idR (const idR) (extractR r) -- we don't descend into the AltCon or Vars-      {-# INLINE allRalt #-}--      allRexpr :: MonadCatch m => Rewrite c m CoreExpr-      allRexpr = readerT $ \case-                              App{}      -> appAllR (extractR r) (extractR r)-                              Lam{}      -> lamAllR idR (extractR r) -- we don't descend into the Var-                              Let{}      -> letAllR (extractR r) (extractR r)-                              Case{}     -> caseAllR (extractR r) idR (extractR r) (const $ extractR r) -- we don't descend into the case binder-                              Cast{}     -> castAllR (extractR r) (extractR r)-                              Tick{}     -> tickAllR idR (extractR r) -- we don't descend into the Tickish-                              Type{}     -> typeR (extractR r)-                              Coercion{} -> coercionR (extractR r)-                              _          -> idR-      {-# INLINE allRexpr #-}--------------------------------------------------------------------------- | Translate a module.---   Slightly different to the other congruence combinators: it passes in /all/ of the original to the reconstruction function.-modGutsT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreProg a -> (ModGuts -> a -> b) -> Translate c m ModGuts b-modGutsT t f = translate $ \ c guts -> f guts <$> apply t (c @@ ModGuts_Prog) (bindsToProg $ mg_binds guts)-{-# INLINE modGutsT #-}---- | Rewrite the 'CoreProg' child of a module.-modGutsR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreProg -> Rewrite c m ModGuts-modGutsR r = modGutsT r (\ guts p -> guts {mg_binds = progToBinds p})-{-# INLINE modGutsR #-}--------------------------------------------------------------------------- | Translate an empty list.-progNilT :: Monad m => b -> Translate c m CoreProg b-progNilT b = contextfreeT $ \case-                               ProgNil       -> return b-                               ProgCons _ _  -> fail "not an empty program."-{-# INLINE progNilT #-}---- | Translate a program of the form: ('CoreBind' @:@ 'CoreProg')-progConsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreProg a2 -> (a1 -> a2 -> b) -> Translate c m CoreProg b-progConsT t1 t2 f = translate $ \ c -> \case-                                          ProgCons bd p -> f <$> apply t1 (c @@ ProgCons_Head) bd <*> apply t2 (addBindingGroup bd c @@ ProgCons_Tail) p-                                          _             -> fail "not a non-empty program."-{-# INLINE progConsT #-}---- | Rewrite all children of a program of the form: ('CoreBind' @:@ 'CoreProg')-progConsAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg-progConsAllR r1 r2 = progConsT r1 r2 ProgCons-{-# INLINE progConsAllR #-}---- | Rewrite any children of a program of the form: ('CoreBind' @:@ 'CoreProg')-progConsAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg-progConsAnyR r1 r2 = unwrapAnyR $ progConsAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE progConsAnyR #-}---- | Rewrite one child of a program of the form: ('CoreBind' @:@ 'CoreProg')-progConsOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreProg -> Rewrite c m CoreProg-progConsOneR r1 r2 = unwrapOneR $  progConsAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE progConsOneR #-}--------------------------------------------------------------------------- | Translate a binding group of the form: @NonRec@ 'Var' 'CoreExpr'-nonRecT :: (ExtendPath c Crumb, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreBind b-nonRecT t1 t2 f = translate $ \ c -> \case-                                        NonRec v e -> f <$> apply t1 (c @@ NonRec_Var) v <*> apply t2 (c @@ NonRec_RHS) e-                                        _          -> fail "not a non-recursive binding group."-{-# INLINE nonRecT #-}---- | Rewrite all children of a binding group of the form: @NonRec@ 'Var' 'CoreExpr'-nonRecAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind-nonRecAllR r1 r2 = nonRecT r1 r2 NonRec-{-# INLINE nonRecAllR #-}---- | Rewrite any children of a binding group of the form: @NonRec@ 'Var' 'CoreExpr'-nonRecAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind-nonRecAnyR r1 r2 = unwrapAnyR (nonRecAllR (wrapAnyR r1) (wrapAnyR r2))-{-# INLINE nonRecAnyR #-}---- | Rewrite one child of a binding group of the form: @NonRec@ 'Var' 'CoreExpr'-nonRecOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreBind-nonRecOneR r1 r2 = unwrapOneR (nonRecAllR (wrapOneR r1) (wrapOneR r2))-{-# INLINE nonRecOneR #-}----- | Translate a binding group of the form: @Rec@ ['CoreDef']-recT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a) -> ([a] -> b) -> Translate c m CoreBind b-recT t f = translate $ \ c -> \case-         Rec bds -> -- Notice how we add the scoping bindings here *before* descending into each individual definition.-                    let c' = addBindingGroup (Rec bds) c-                     in f <$> sequence [ apply (t n) (c' @@ Rec_Def n) (Def v e) -- here we convert from (Id,CoreExpr) to CoreDef-                                       | ((v,e),n) <- zip bds [0..]-                                       ]-         _       -> fail "not a recursive binding group."-{-# INLINE recT #-}---- | Rewrite all children of a binding group of the form: @Rec@ ['CoreDef']-recAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind-recAllR rs = recT rs defsToRecBind-{-# INLINE recAllR #-}---- | Rewrite any children of a binding group of the form: @Rec@ ['CoreDef']-recAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind-recAnyR rs = unwrapAnyR $ recAllR (wrapAnyR . rs)-{-# INLINE recAnyR #-}---- | Rewrite one child of a binding group of the form: @Rec@ ['CoreDef']-recOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreBind-recOneR rs = unwrapOneR $ recAllR (wrapOneR . rs)-{-# INLINE recOneR #-}--------------------------------------------------------------------------- | Translate a recursive definition of the form: @Def@ 'Id' 'CoreExpr'-defT :: (ExtendPath c Crumb, Monad m) => Translate c m Id a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreDef b-defT t1 t2 f = translate $ \ c (Def v e) -> f <$> apply t1 (c @@ Def_Id) v <*> apply t2 (c @@ Def_RHS) e-{-# INLINE defT #-}---- | Rewrite all children of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'-defAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef-defAllR r1 r2 = defT r1 r2 Def-{-# INLINE defAllR #-}---- | Rewrite any children of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'-defAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef-defAnyR r1 r2 = unwrapAnyR (defAllR (wrapAnyR r1) (wrapAnyR r2))-{-# INLINE defAnyR #-}---- | Rewrite one child of a recursive definition of the form: @Def@ 'Id' 'CoreExpr'-defOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Id -> Rewrite c m CoreExpr -> Rewrite c m CoreDef-defOneR r1 r2 = unwrapOneR (defAllR (wrapOneR r1) (wrapOneR r2))-{-# INLINE defOneR #-}--------------------------------------------------------------------------- | Translate a case alternative of the form: ('AltCon', ['Var'], 'CoreExpr')-altT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m AltCon a1 -> (Int -> Translate c m Var a2) -> Translate c m CoreExpr a3 -> (a1 -> [a2] -> a3 -> b) -> Translate c m CoreAlt b-altT t1 ts t2 f = translate $ \ c (con,vs,e) -> f <$> apply t1 (c @@ Alt_Con) con-                                                  <*> sequence [ apply (ts n) (c @@ Alt_Var n) v | (v,n) <- zip vs [1..] ]-                                                  <*> apply t2 (addAltBindings vs c @@ Alt_RHS) e-{-# INLINE altT #-}---- | Rewrite all children of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')-altAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt-altAllR r1 rs r2 = altT r1 rs r2 (,,)-{-# INLINE altAllR #-}---- | Rewrite any children of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')-altAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt-altAnyR r1 rs r2 = unwrapAnyR (altAllR (wrapAnyR r1) (wrapAnyR . rs) (wrapAnyR r2))-{-# INLINE altAnyR #-}---- | Rewrite one child of a case alternative of the form: ('AltCon', 'Id', 'CoreExpr')-altOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m AltCon -> (Int -> Rewrite c m Var) -> Rewrite c m CoreExpr -> Rewrite c m CoreAlt-altOneR r1 rs r2 = unwrapOneR (altAllR (wrapOneR r1) (wrapOneR . rs) (wrapOneR r2))-{-# INLINE altOneR #-}--------------------------------------------------------------------------- | Translate an expression of the form: @Var@ 'Id'-varT :: (ExtendPath c Crumb, Monad m) => Translate c m Id b -> Translate c m CoreExpr b-varT t = translate $ \ c -> \case-                               Var v -> apply t (c @@ Var_Id) v-                               _     -> fail "not a variable."-{-# INLINE varT #-}---- | Rewrite the 'Id' child in an expression of the form: @Var@ 'Id'-varR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Id -> Rewrite c m CoreExpr-varR r = varT (Var <$> r)-{-# INLINE varR #-}----- | Translate an expression of the form: @Lit@ 'Literal'-litT :: (ExtendPath c Crumb, Monad m) => Translate c m Literal b -> Translate c m CoreExpr b-litT t = translate $ \ c -> \case-                               Lit x -> apply t (c @@ Lit_Lit) x-                               _     -> fail "not a literal."-{-# INLINE litT #-}---- | Rewrite the 'Literal' child in an expression of the form: @Lit@ 'Literal'-litR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Literal -> Rewrite c m CoreExpr-litR r = litT (Lit <$> r)-{-# INLINE litR #-}----- | Translate an expression of the form: @App@ 'CoreExpr' 'CoreExpr'-appT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b-appT t1 t2 f = translate $ \ c -> \case-                                     App e1 e2 -> f <$> apply t1 (c @@ App_Fun) e1 <*> apply t2 (c @@ App_Arg) e2-                                     _         -> fail "not an application."-{-# INLINE appT #-}---- | Rewrite all children of an expression of the form: @App@ 'CoreExpr' 'CoreExpr'-appAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-appAllR r1 r2 = appT r1 r2 App-{-# INLINE appAllR #-}---- | Rewrite any children of an expression of the form: @App@ 'CoreExpr' 'CoreExpr'-appAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-appAnyR r1 r2 = unwrapAnyR $ appAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE appAnyR #-}---- | Rewrite one child of an expression of the form: @App@ 'CoreExpr' 'CoreExpr'-appOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-appOneR r1 r2 = unwrapOneR $ appAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE appOneR #-}----- | Translate an expression of the form: @Lam@ 'Var' 'CoreExpr'-lamT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b-lamT t1 t2 f = translate $ \ c -> \case-                                     Lam v e -> f <$> apply t1 (c @@ Lam_Var) v <*> apply t2 (addLambdaBinding v c @@ Lam_Body) e-                                     _       -> fail "not a lambda."-{-# INLINE lamT #-}---- | Rewrite all children of an expression of the form: @Lam@ 'Var' 'CoreExpr'-lamAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-lamAllR r1 r2 = lamT r1 r2 Lam-{-# INLINE lamAllR #-}---- | Rewrite any children of an expression of the form: @Lam@ 'Var' 'CoreExpr'-lamAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-lamAnyR r1 r2 = unwrapAnyR $ lamAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE lamAnyR #-}---- | Rewrite one child of an expression of the form: @Lam@ 'Var' 'CoreExpr'-lamOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-lamOneR r1 r2 = unwrapOneR $ lamAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE lamOneR #-}----- | Translate an expression of the form: @Let@ 'CoreBind' 'CoreExpr'-letT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b-letT t1 t2 f = translate $ \ c -> \case-        Let bds e -> -- Note we use the *original* context for the binding group.-                     -- If the bindings are recursive, they will be added to the context by recT.-                     f <$> apply t1 (c @@ Let_Bind) bds <*> apply t2 (addBindingGroup bds c @@ Let_Body) e-        _         -> fail "not a let node."-{-# INLINE letT #-}---- | Rewrite all children of an expression of the form: @Let@ 'CoreBind' 'CoreExpr'-letAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letAllR r1 r2 = letT r1 r2 Let-{-# INLINE letAllR #-}---- | Rewrite any children of an expression of the form: @Let@ 'CoreBind' 'CoreExpr'-letAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letAnyR r1 r2 = unwrapAnyR $ letAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE letAnyR #-}---- | Rewrite one child of an expression of the form: @Let@ 'CoreBind' 'CoreExpr'-letOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreBind -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letOneR r1 r2 = unwrapOneR $ letAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE letOneR #-}----- | Translate an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']-caseT :: (ExtendPath c Crumb, AddBindings c, Monad m)-      => Translate c m CoreExpr e-      -> Translate c m Id w-      -> Translate c m Type ty-      -> (Int -> Translate c m CoreAlt alt)-      -> (e -> w -> ty -> [alt] -> b)-      -> Translate c m CoreExpr b-caseT te tw tty talts f = translate $ \ c -> \case-         Case e w ty alts -> f <$> apply te (c @@ Case_Scrutinee) e-                               <*> apply tw (c @@ Case_Binder) w-                               <*> apply tty (c @@ Case_Type) ty-                               <*> sequence [ apply (talts n) (addCaseWildBinding (w,e,alt) c @@ Case_Alt n) alt-                                            | (alt,n) <- zip alts [0..]-                                            ]-         _                -> fail "not a case."-{-# INLINE caseT #-}---- | Rewrite all children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']-caseAllR :: (ExtendPath c Crumb, AddBindings c, Monad m)-         => Rewrite c m CoreExpr-         -> Rewrite c m Id-         -> Rewrite c m Type-         -> (Int -> Rewrite c m CoreAlt)-         -> Rewrite c m CoreExpr-caseAllR re rw rty ralts = caseT re rw rty ralts Case-{-# INLINE caseAllR #-}---- | Rewrite any children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']-caseAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)-         => Rewrite c m CoreExpr-         -> Rewrite c m Id-         -> Rewrite c m Type-         -> (Int -> Rewrite c m CoreAlt)-         -> Rewrite c m CoreExpr-caseAnyR re rw rty ralts = unwrapAnyR $ caseAllR (wrapAnyR re) (wrapAnyR rw) (wrapAnyR rty) (wrapAnyR . ralts)-{-# INLINE caseAnyR #-}---- | Rewrite one child of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' ['CoreAlt']-caseOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)-         => Rewrite c m CoreExpr-         -> Rewrite c m Id-         -> Rewrite c m Type-         -> (Int -> Rewrite c m CoreAlt)-         -> Rewrite c m CoreExpr-caseOneR re rw rty ralts = unwrapOneR $ caseAllR (wrapOneR re) (wrapOneR rw) (wrapOneR rty) (wrapOneR . ralts)-{-# INLINE caseOneR #-}----- | Translate an expression of the form: @Cast@ 'CoreExpr' 'Coercion'-castT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b-castT t1 t2 f = translate $ \ c -> \case-                                      Cast e co -> f <$> apply t1 (c @@ Cast_Expr) e <*> apply t2 (c @@ Cast_Co) co-                                      _         -> fail "not a cast."-{-# INLINE castT #-}---- | Rewrite all children of an expression of the form: @Cast@ 'CoreExpr' 'Coercion'-castAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr-castAllR r1 r2 = castT r1 r2 Cast-{-# INLINE castAllR #-}---- | Rewrite any children of an expression of the form: @Cast@ 'CoreExpr' 'Coercion'-castAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr-castAnyR r1 r2 = unwrapAnyR $ castAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE castAnyR #-}---- | Rewrite one child of an expression of the form: @Cast@ 'CoreExpr' 'Coercion'-castOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreExpr -> Rewrite c m Coercion -> Rewrite c m CoreExpr-castOneR r1 r2 = unwrapOneR $ castAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE castOneR #-}----- | Translate an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'-tickT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreTickish a1 -> Translate c m CoreExpr a2 -> (a1 -> a2 -> b) -> Translate c m CoreExpr b-tickT t1 t2 f = translate $ \ c -> \case-                                      Tick tk e -> f <$> apply t1 (c @@ Tick_Tick) tk <*> apply t2 (c @@ Tick_Expr) e-                                      _         -> fail "not a tick."-{-# INLINE tickT #-}---- | Rewrite all children of an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'-tickAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-tickAllR r1 r2 = tickT r1 r2 Tick-{-# INLINE tickAllR #-}---- | Rewrite any children of an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'-tickAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-tickAnyR r1 r2 = unwrapAnyR $ tickAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE tickAnyR #-}---- | Rewrite any children of an expression of the form: @Tick@ 'CoreTickish' 'CoreExpr'-tickOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoreTickish -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-tickOneR r1 r2 = unwrapOneR $ tickAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE tickOneR #-}----- | Translate an expression of the form: @Type@ 'Type'-typeT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m CoreExpr b-typeT t = translate $ \ c -> \case-                                Type ty -> apply t (c @@ Type_Type) ty-                                _       -> fail "not a type."-{-# INLINE typeT #-}---- | Rewrite the 'Type' child in an expression of the form: @Type@ 'Type'-typeR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m CoreExpr-typeR r = typeT (Type <$> r)-{-# INLINE typeR #-}----- | Translate an expression of the form: @Coercion@ 'Coercion'-coercionT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m CoreExpr b-coercionT t = translate $ \ c -> \case-                                    Coercion co -> apply t (c @@ Co_Co) co-                                    _           -> fail "not a coercion."-{-# INLINE coercionT #-}---- | Rewrite the 'Coercion' child in an expression of the form: @Coercion@ 'Coercion'-coercionR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m CoreExpr-coercionR r = coercionT (Coercion <$> r)-{-# INLINE coercionR #-}--------------------------------------------------------------------------- Some composite congruence combinators to export.---- | Translate a binding group of the form: @Rec@ [('Id', 'CoreExpr')]-recDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> ([(a1,a2)] -> b) -> Translate c m CoreBind b-recDefT ts = recT (\ n -> uncurry defT (ts n) (,))-{-# INLINE recDefT #-}---- | Rewrite all children of a binding group of the form: @Rec@ [('Id', 'CoreExpr')]-recDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind-recDefAllR rs = recAllR (\ n -> uncurry defAllR (rs n))-{-# INLINE recDefAllR #-}---- | Rewrite any children of a binding group of the form: @Rec@ [('Id', 'CoreExpr')]-recDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind-recDefAnyR rs = recAnyR (\ n -> uncurry defAnyR (rs n))-{-# INLINE recDefAnyR #-}---- | Rewrite one child of a binding group of the form: @Rec@ [('Id', 'CoreExpr')]-recDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreBind-recDefOneR rs = recOneR (\ n -> uncurry defOneR (rs n))-{-# INLINE recDefOneR #-}----- | Translate a program of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'-consNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreProg a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreProg b-consNonRecT t1 t2 t3 f = progConsT (nonRecT t1 t2 (,)) t3 (uncurry f)-{-# INLINE consNonRecT #-}---- | Rewrite all children of an expression of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'-consNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consNonRecAllR r1 r2 r3 = progConsAllR (nonRecAllR r1 r2) r3-{-# INLINE consNonRecAllR #-}---- | Rewrite any children of an expression of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'-consNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consNonRecAnyR r1 r2 r3 = progConsAllR (nonRecAnyR r1 r2) r3-{-# INLINE consNonRecAnyR #-}---- | Rewrite one child of an expression of the form: (@NonRec@ 'Var' 'CoreExpr') @:@ 'CoreProg'-consNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consNonRecOneR r1 r2 r3 = progConsAllR (nonRecOneR r1 r2) r3-{-# INLINE consNonRecOneR #-}----- | Translate an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'-consRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreProg a2 -> ([a1] -> a2 -> b) -> Translate c m CoreProg b-consRecT ts t = progConsT (recT ts id) t-{-# INLINE consRecT #-}---- | Rewrite all children of an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'-consRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consRecAllR rs r = progConsAllR (recAllR rs) r-{-# INLINE consRecAllR #-}---- | Rewrite any children of an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'-consRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consRecAnyR rs r = progConsAnyR (recAnyR rs) r-{-# INLINE consRecAnyR #-}---- | Rewrite one child of an expression of the form: (@Rec@ ['CoreDef']) @:@ 'CoreProg'-consRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consRecOneR rs r = progConsOneR (recOneR rs) r-{-# INLINE consRecOneR #-}----- | Translate an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'-consRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreProg a3 -> ([(a1,a2)] -> a3 -> b) -> Translate c m CoreProg b-consRecDefT ts t = consRecT (\ n -> uncurry defT (ts n) (,)) t-{-# INLINE consRecDefT #-}---- | Rewrite all children of an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'-consRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consRecDefAllR rs r = consRecAllR (\ n -> uncurry defAllR (rs n)) r-{-# INLINE consRecDefAllR #-}---- | Rewrite any children of an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'-consRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consRecDefAnyR rs r = consRecAnyR (\ n -> uncurry defAnyR (rs n)) r-{-# INLINE consRecDefAnyR #-}---- | Rewrite one child of an expression of the form: (@Rec@ [('Id', 'CoreExpr')]) @:@ 'CoreProg'-consRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreProg -> Rewrite c m CoreProg-consRecDefOneR rs r = consRecOneR (\ n -> uncurry defOneR (rs n)) r-{-# INLINE consRecDefOneR #-}----- | Translate an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'-letNonRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m CoreExpr a2 -> Translate c m CoreExpr a3 -> (a1 -> a2 -> a3 -> b) -> Translate c m CoreExpr b-letNonRecT t1 t2 t3 f = letT (nonRecT t1 t2 (,)) t3 (uncurry f)-{-# INLINE letNonRecT #-}---- | Rewrite all children of an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'-letNonRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letNonRecAllR r1 r2 r3 = letAllR (nonRecAllR r1 r2) r3-{-# INLINE letNonRecAllR #-}---- | Rewrite any children of an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'-letNonRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letNonRecAnyR r1 r2 r3 = letAnyR (nonRecAnyR r1 r2) r3-{-# INLINE letNonRecAnyR #-}---- | Rewrite one child of an expression of the form: @Let@ (@NonRec@ 'Var' 'CoreExpr') 'CoreExpr'-letNonRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letNonRecOneR r1 r2 r3 = letOneR (nonRecOneR r1 r2) r3-{-# INLINE letNonRecOneR #-}----- | Translate an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'-letRecT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Translate c m CoreDef a1) -> Translate c m CoreExpr a2 -> ([a1] -> a2 -> b) -> Translate c m CoreExpr b-letRecT ts t = letT (recT ts id) t-{-# INLINE letRecT #-}---- | Rewrite all children of an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'-letRecAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letRecAllR rs r = letAllR (recAllR rs) r-{-# INLINE letRecAllR #-}---- | Rewrite any children of an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'-letRecAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letRecAnyR rs r = letAnyR (recAnyR rs) r-{-# INLINE letRecAnyR #-}---- | Rewrite one child of an expression of the form: @Let@ (@Rec@ ['CoreDef']) 'CoreExpr'-letRecOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> Rewrite c m CoreDef) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letRecOneR rs r = letOneR (recOneR rs) r-{-# INLINE letRecOneR #-}----- | Translate an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'-letRecDefT :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Translate c m Id a1, Translate c m CoreExpr a2)) -> Translate c m CoreExpr a3 -> ([(a1,a2)] -> a3 -> b) -> Translate c m CoreExpr b-letRecDefT ts t = letRecT (\ n -> uncurry defT (ts n) (,)) t-{-# INLINE letRecDefT #-}---- | Rewrite all children of an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'-letRecDefAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letRecDefAllR rs r = letRecAllR (\ n -> uncurry defAllR (rs n)) r-{-# INLINE letRecDefAllR #-}---- | Rewrite any children of an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'-letRecDefAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letRecDefAnyR rs r = letRecAnyR (\ n -> uncurry defAnyR (rs n)) r-{-# INLINE letRecDefAnyR #-}---- | Rewrite one child of an expression of the form: @Let@ (@Rec@ [('Id', 'CoreExpr')]) 'CoreExpr'-letRecDefOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => (Int -> (Rewrite c m Id, Rewrite c m CoreExpr)) -> Rewrite c m CoreExpr -> Rewrite c m CoreExpr-letRecDefOneR rs r = letRecOneR (\ n -> uncurry defOneR (rs n)) r-{-# INLINE letRecDefOneR #-}----- | Translate an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]-caseAltT :: (ExtendPath c Crumb, AddBindings c, Monad m)-         => Translate c m CoreExpr sc-         -> Translate c m Id w-         -> Translate c m Type ty-         -> (Int -> (Translate c m AltCon con, (Int -> Translate c m Var v), Translate c m CoreExpr rhs)) -> (sc -> w -> ty -> [(con,[v],rhs)] -> b)-         -> Translate c m CoreExpr b-caseAltT tsc tw tty talts = caseT tsc tw tty (\ n -> let (tcon,tvs,te) = talts n in altT tcon tvs te (,,))-{-# INLINE caseAltT #-}---- | Rewrite all children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]-caseAltAllR :: (ExtendPath c Crumb, AddBindings c, Monad m)-            => Rewrite c m CoreExpr-            -> Rewrite c m Id-            -> Rewrite c m Type-            -> (Int -> (Rewrite c m AltCon, (Int -> Rewrite c m Var), Rewrite c m CoreExpr))-            -> Rewrite c m CoreExpr-caseAltAllR rsc rw rty ralts = caseAllR rsc rw rty (\ n -> let (rcon,rvs,re) = ralts n in altAllR rcon rvs re)-{-# INLINE caseAltAllR #-}---- | Rewrite any children of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]-caseAltAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)-            => Rewrite c m CoreExpr-            -> Rewrite c m Id-            -> Rewrite c m Type-            -> (Int -> (Rewrite c m AltCon, (Int -> Rewrite c m Var), Rewrite c m CoreExpr))-            -> Rewrite c m CoreExpr-caseAltAnyR rsc rw rty ralts = caseAnyR rsc rw rty (\ n -> let (rcon,rvs,re) = ralts n in altAnyR rcon rvs re)-{-# INLINE caseAltAnyR #-}---- | Rewrite one child of an expression of the form: @Case@ 'CoreExpr' 'Id' 'Type' [('AltCon', ['Var'], 'CoreExpr')]-caseAltOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m)-            => Rewrite c m CoreExpr-            -> Rewrite c m Id-            -> Rewrite c m Type-            -> (Int -> (Rewrite c m AltCon, (Int -> Rewrite c m Var), Rewrite c m CoreExpr))-            -> Rewrite c m CoreExpr-caseAltOneR rsc rw rty ralts = caseOneR rsc rw rty (\ n -> let (rcon,rvs,re) = ralts n in altOneR rcon rvs re)-{-# INLINE caseAltOneR #-}--------------------------------------------------------------------------- | Promote a rewrite on 'ModGuts' to a rewrite on 'Core'.-promoteModGutsR :: (ExtendPath c Crumb, Monad m) => Rewrite c m ModGuts -> Rewrite c m Core-promoteModGutsR = promoteWithFailMsgR "This rewrite can only succeed at the module level."-{-# INLINE promoteModGutsR #-}---- | Promote a rewrite on 'CoreProg' to a rewrite on 'Core'.-promoteProgR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreProg -> Rewrite c m Core-promoteProgR = promoteWithFailMsgR "This rewrite can only succeed at program nodes (the top-level)."-{-# INLINE promoteProgR #-}---- | Promote a rewrite on 'CoreBind' to a rewrite on 'Core'.-promoteBindR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreBind -> Rewrite c m Core-promoteBindR = promoteWithFailMsgR "This rewrite can only succeed at binding group nodes."-{-# INLINE promoteBindR #-}---- | Promote a rewrite on 'CoreDef' to a rewrite on 'Core'.-promoteDefR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreDef -> Rewrite c m Core-promoteDefR = promoteWithFailMsgR "This rewrite can only succeed at recursive definition nodes."-{-# INLINE promoteDefR #-}---- | Promote a rewrite on 'CoreAlt' to a rewrite on 'Core'.-promoteAltR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreAlt -> Rewrite c m Core-promoteAltR = promoteWithFailMsgR "This rewrite can only succeed at case alternative nodes."-{-# INLINE promoteAltR #-}---- | Promote a rewrite on 'CoreExpr' to a rewrite on 'Core'.-promoteExprR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr -> Rewrite c m Core-promoteExprR = promoteWithFailMsgR "This rewrite can only succeed at expression nodes."-{-# INLINE promoteExprR #-}--------------------------------------------------------------------------- | Promote a bidirectional rewrite on 'CoreExpr' to a bidirectional rewrite on 'Core'.-promoteExprBiR :: (ExtendPath c Crumb, Monad m) => BiRewrite c m CoreExpr -> BiRewrite c m Core-promoteExprBiR b = bidirectional (promoteExprR $ forewardT b) (promoteExprR $ backwardT b)-{-# INLINE promoteExprBiR #-}--------------------------------------------------------------------------- | Promote a translate on 'ModGuts' to a translate on 'Core'.-promoteModGutsT :: (ExtendPath c Crumb, Monad m) => Translate c m ModGuts b -> Translate c m Core b-promoteModGutsT = promoteWithFailMsgT "This translate can only succeed at the module level."-{-# INLINE promoteModGutsT #-}---- | Promote a translate on 'CoreProg' to a translate on 'Core'.-promoteProgT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreProg b -> Translate c m Core b-promoteProgT = promoteWithFailMsgT "This translate can only succeed at program nodes (the top-level)."-{-# INLINE promoteProgT #-}---- | Promote a translate on 'CoreBind' to a translate on 'Core'.-promoteBindT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreBind b -> Translate c m Core b-promoteBindT = promoteWithFailMsgT "This translate can only succeed at binding group nodes."-{-# INLINE promoteBindT #-}---- | Promote a translate on 'CoreDef' to a translate on 'Core'.-promoteDefT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreDef b -> Translate c m Core b-promoteDefT = promoteWithFailMsgT "This translate can only succeed at recursive definition nodes."-{-# INLINE promoteDefT #-}---- | Promote a translate on 'CoreAlt' to a translate on 'Core'.-promoteAltT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreAlt b -> Translate c m Core b-promoteAltT = promoteWithFailMsgT "This translate can only succeed at case alternative nodes."-{-# INLINE promoteAltT #-}---- | Promote a translate on 'CoreExpr' to a translate on 'Core'.-promoteExprT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreExpr b -> Translate c m Core b-promoteExprT = promoteWithFailMsgT "This translate can only succeed at expression nodes."-{-# INLINE promoteExprT #-}-------------------------------------------------------------------------------------------------------------------------------------------------- Types---- | Translate a type of the form: @TyVarTy@ 'TyVar'-tyVarT :: (ExtendPath c Crumb, Monad m) => Translate c m TyVar b -> Translate c m Type b-tyVarT t = translate $ \ c -> \case-                                 TyVarTy v -> apply t (c @@ TyVarTy_TyVar) v-                                 _         -> fail "not a type variable."-{-# INLINE tyVarT #-}---- | Rewrite the 'TyVar' child of a type of the form: @TyVarTy@ 'TyVar'-tyVarR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyVar -> Rewrite c m Type-tyVarR r = tyVarT (TyVarTy <$> r)-{-# INLINE tyVarR #-}----- | Translate a type of the form: @LitTy@ 'TyLit'-litTyT :: (ExtendPath c Crumb, Monad m) => Translate c m TyLit b -> Translate c m Type b-litTyT t = translate $ \ c -> \case-                                 LitTy x -> apply t (c @@ LitTy_TyLit) x-                                 _       -> fail "not a type literal."-{-# INLINE litTyT #-}---- | Rewrite the 'TyLit' child of a type of the form: @LitTy@ 'TyLit'-litTyR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyLit -> Rewrite c m Type-litTyR r = litTyT (LitTy <$> r)-{-# INLINE litTyR #-}----- | Translate a type of the form: @AppTy@ 'Type' 'Type'-appTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b-appTyT t1 t2 f = translate $ \ c -> \case-                                     AppTy ty1 ty2 -> f <$> apply t1 (c @@ AppTy_Fun) ty1 <*> apply t2 (c @@ AppTy_Arg) ty2-                                     _             -> fail "not a type application."-{-# INLINE appTyT #-}---- | Rewrite all children of a type of the form: @AppTy@ 'Type' 'Type'-appTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type-appTyAllR r1 r2 = appTyT r1 r2 AppTy-{-# INLINE appTyAllR #-}---- | Rewrite any children of a type of the form: @AppTy@ 'Type' 'Type'-appTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type-appTyAnyR r1 r2 = unwrapAnyR $ appTyAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE appTyAnyR #-}---- | Rewrite one child of a type of the form: @AppTy@ 'Type' 'Type'-appTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type-appTyOneR r1 r2 = unwrapOneR $ appTyAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE appTyOneR #-}----- | Translate a type of the form: @FunTy@ 'Type' 'Type'-funTyT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b-funTyT t1 t2 f = translate $ \ c -> \case-                                     FunTy ty1 ty2 -> f <$> apply t1 (c @@ FunTy_Dom) ty1 <*> apply t2 (c @@ FunTy_CoDom) ty2-                                     _             -> fail "not a function type."-{-# INLINE funTyT #-}---- | Rewrite all children of a type of the form: @FunTy@ 'Type' 'Type'-funTyAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type-funTyAllR r1 r2 = funTyT r1 r2 FunTy-{-# INLINE funTyAllR #-}---- | Rewrite any children of a type of the form: @FunTy@ 'Type' 'Type'-funTyAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type-funTyAnyR r1 r2 = unwrapAnyR $ funTyAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE funTyAnyR #-}---- | Rewrite one child of a type of the form: @FunTy@ 'Type' 'Type'-funTyOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Type-funTyOneR r1 r2 = unwrapOneR $ funTyAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE funTyOneR #-}----- | Translate a type of the form: @ForAllTy@ 'Var' 'Type'-forAllTyT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m Var a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Type b-forAllTyT t1 t2 f = translate $ \ c -> \case-                                          ForAllTy v ty -> f <$> apply t1 (c @@ ForAllTy_Var) v <*> apply t2 (addForallBinding v c @@ ForAllTy_Body) ty-                                          _             -> fail "not a forall type."-{-# INLINE forAllTyT #-}---- | Rewrite all children of a type of the form: @ForAllTy@ 'Var' 'Type'-forAllTyAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type-forAllTyAllR r1 r2 = forAllTyT r1 r2 ForAllTy-{-# INLINE forAllTyAllR #-}---- | Rewrite any children of a type of the form: @ForAllTy@ 'Var' 'Type'-forAllTyAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type-forAllTyAnyR r1 r2 = unwrapAnyR $ forAllTyAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE forAllTyAnyR #-}---- | Rewrite one child of a type of the form: @ForAllTy@ 'Var' 'Type'-forAllTyOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m Var -> Rewrite c m Type -> Rewrite c m Type-forAllTyOneR r1 r2 = unwrapOneR $ forAllTyAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE forAllTyOneR #-}----- | Translate a type of the form: @TyConApp@ 'TyCon' ['KindOrType']-tyConAppT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m KindOrType a2) -> (a1 -> [a2] -> b) -> Translate c m Type b-tyConAppT t ts f = translate $ \ c -> \case-                                         TyConApp con tys -> f <$> apply t (c @@ TyConApp_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConApp_Arg n) ty | (ty,n) <- zip tys [0..] ]-                                         _                -> fail "not a type-constructor application."-{-# INLINE tyConAppT #-}---- | Rewrite all children of a type of the form: @TyConApp@ 'TyCon' ['KindOrType']-tyConAppAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type-tyConAppAllR r rs = tyConAppT r rs TyConApp-{-# INLINE tyConAppAllR #-}---- | Rewrite any children of a type of the form: @TyConApp@ 'TyCon' ['KindOrType']-tyConAppAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type-tyConAppAnyR r rs = unwrapAnyR $ tyConAppAllR (wrapAnyR r) (wrapAnyR . rs)-{-# INLINE tyConAppAnyR #-}---- | Rewrite one child of a type of the form: @TyConApp@ 'TyCon' ['KindOrType']-tyConAppOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m KindOrType) -> Rewrite c m Type-tyConAppOneR r rs = unwrapOneR $ tyConAppAllR (wrapOneR r) (wrapOneR . rs)-{-# INLINE tyConAppOneR #-}------------------------------------------------------------------------------------------------------------------------------------------------- Coercions---- | Translate a coercion of the form: @Refl@ 'Type'-reflT :: (ExtendPath c Crumb, Monad m) => Translate c m Type b -> Translate c m Coercion b-reflT t = translate $ \ c -> \case-                                 Refl ty -> apply t (c @@ Refl_Type) ty-                                 _       -> fail "not a reflexive coercion."-{-# INLINE reflT #-}---- | Rewrite the 'Type' child of a coercion of the form: @Refl@ 'Type'-reflR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Coercion-reflR r = reflT (Refl <$> r)-{-# INLINE reflR #-}----- | Translate a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']-tyConAppCoT :: (ExtendPath c Crumb, Monad m) => Translate c m TyCon a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b-tyConAppCoT t ts f = translate $ \ c -> \case-                                           TyConAppCo con coes -> f <$> apply t (c @@ TyConAppCo_TyCon) con <*> sequence [ apply (ts n) (c @@ TyConAppCo_Arg n) co | (co,n) <- zip coes [0..] ]-                                           _                   -> fail "not a type-constructor coercion."-{-# INLINE tyConAppCoT #-}---- | Rewrite all children of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']-tyConAppCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-tyConAppCoAllR r rs = tyConAppCoT r rs TyConAppCo-{-# INLINE tyConAppCoAllR #-}---- | Rewrite any children of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']-tyConAppCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-tyConAppCoAnyR r rs = unwrapAnyR $ tyConAppCoAllR (wrapAnyR r) (wrapAnyR . rs)-{-# INLINE tyConAppCoAnyR #-}---- | Rewrite one child of a coercion of the form: @TyConAppCo@ 'TyCon' ['Coercion']-tyConAppCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m TyCon -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-tyConAppCoOneR r rs = unwrapOneR $ tyConAppCoAllR (wrapOneR r) (wrapOneR . rs)-{-# INLINE tyConAppCoOneR #-}----- | Translate a coercion of the form: @AppCo@ 'Coercion' 'Coercion'-appCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-appCoT t1 t2 f = translate $ \ c -> \case-                                     AppCo co1 co2 -> f <$> apply t1 (c @@ AppCo_Fun) co1 <*> apply t2 (c @@ AppCo_Arg) co2-                                     _             -> fail "not a coercion application."-{-# INLINE appCoT #-}---- | Rewrite all children of a coercion of the form: @AppCo@ 'Coercion' 'Coercion'-appCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion-appCoAllR r1 r2 = appCoT r1 r2 AppCo-{-# INLINE appCoAllR #-}---- | Rewrite any children of a coercion of the form: @AppCo@ 'Coercion' 'Coercion'-appCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion-appCoAnyR r1 r2 = unwrapAnyR $ appCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE appCoAnyR #-}---- | Rewrite one child of a coercion of the form: @AppCo@ 'Coercion' 'Coercion'-appCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion-appCoOneR r1 r2 = unwrapOneR $ appCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE appCoOneR #-}----- | Translate a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'-forAllCoT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m TyVar a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-forAllCoT t1 t2 f = translate $ \ c -> \case-                                          ForAllCo v co -> f <$> apply t1 (c @@ ForAllCo_TyVar) v <*> apply t2 (addForallBinding v c @@ ForAllCo_Body) co-                                          _             -> fail "not a forall coercion."-{-# INLINE forAllCoT #-}---- | Rewrite all children of a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'-forAllCoAllR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion-forAllCoAllR r1 r2 = forAllCoT r1 r2 ForAllCo-{-# INLINE forAllCoAllR #-}---- | Rewrite any children of a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'-forAllCoAnyR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion-forAllCoAnyR r1 r2 = unwrapAnyR $ forAllCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE forAllCoAnyR #-}---- | Rewrite one child of a coercion of the form: @ForAllCo@ 'TyVar' 'Coercion'-forAllCoOneR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m TyVar -> Rewrite c m Coercion -> Rewrite c m Coercion-forAllCoOneR r1 r2 = unwrapOneR $ forAllCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE forAllCoOneR #-}----- | Translate a coercion of the form: @CoVarCo@ 'CoVar'-coVarCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoVar b -> Translate c m Coercion b-coVarCoT t = translate $ \ c -> \case-                                   CoVarCo v -> apply t (c @@ CoVarCo_CoVar) v-                                   _         -> fail "not a coercion variable."-{-# INLINE coVarCoT #-}---- | Rewrite the 'CoVar' child of a coercion of the form: @CoVarCo@ 'CoVar'-coVarCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoVar -> Rewrite c m Coercion-coVarCoR r = coVarCoT (CoVarCo <$> r)-{-# INLINE coVarCoR #-}--#if __GLASGOW_HASKELL__ > 706--- | Translate a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']-axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Translate c m (CoAxiom Branched) a1 -> Translate c m BranchIndex a2 -> (Int -> Translate c m Coercion a3) -> (a1 -> a2 -> [a3] -> b) -> Translate c m Coercion b-axiomInstCoT t1 t2 ts f = translate $ \ c -> \case-                                                AxiomInstCo ax idx coes -> f <$> apply t1 (c @@ AxiomInstCo_Axiom) ax <*> apply t2 (c @@ AxiomInstCo_Index) idx <*> sequence [ apply (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]-                                                _                       -> fail "not a coercion axiom instantiation."-#else--- | Translate a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoT :: (ExtendPath c Crumb, Monad m) => Translate c m CoAxiom a1 -> (Int -> Translate c m Coercion a2) -> (a1 -> [a2] -> b) -> Translate c m Coercion b-axiomInstCoT t ts f = translate $ \ c -> \case-                                            AxiomInstCo ax coes -> f <$> apply t (c @@ AxiomInstCo_Axiom) ax <*> sequence [ apply (ts n) (c @@ AxiomInstCo_Arg n) co | (co,n) <- zip coes [0..] ]-                                            _                   -> fail "not a coercion axiom instantiation."-#endif-{-# INLINE axiomInstCoT #-}--#if __GLASGOW_HASKELL__ > 706--- | Rewrite all children of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']-axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoAllR r1 r2 rs = axiomInstCoT r1 r2 rs AxiomInstCo-#else--- | Rewrite all children of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoAllR r rs = axiomInstCoT r rs AxiomInstCo-#endif-{-# INLINE axiomInstCoAllR #-}--#if __GLASGOW_HASKELL__ > 706--- | Rewrite any children of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']-axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoAnyR r1 r2 rs = unwrapAnyR $ axiomInstCoAllR (wrapAnyR r1) (wrapAnyR r2) (wrapAnyR . rs)-#else--- | Rewrite any children of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoAnyR r rs = unwrapAnyR $ axiomInstCoAllR (wrapAnyR r) (wrapAnyR . rs)-#endif-{-# INLINE axiomInstCoAnyR #-}--#if __GLASGOW_HASKELL__ > 706--- | Rewrite one child of a coercion of the form: @AxiomInstCo@ ('CoAxiom' 'Branched') 'BranchIndex' ['Coercion']-axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m (CoAxiom Branched) -> Rewrite c m BranchIndex -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoOneR r1 r2 rs = unwrapOneR $ axiomInstCoAllR (wrapOneR r1) (wrapOneR r2) (wrapOneR . rs)-#else--- | Rewrite one child of a coercion of the form: @AxiomInstCo@ 'CoAxiom' ['Coercion']-axiomInstCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m CoAxiom -> (Int -> Rewrite c m Coercion) -> Rewrite c m Coercion-axiomInstCoOneR r rs = unwrapOneR $ axiomInstCoAllR (wrapOneR r) (wrapOneR . rs)-#endif-{-# INLINE axiomInstCoOneR #-}---- | Translate a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Type a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-unsafeCoT t1 t2 f = translate $ \ c -> \case-                                          UnsafeCo ty1 ty2 -> f <$> apply t1 (c @@ UnsafeCo_Left) ty1 <*> apply t2 (c @@ UnsafeCo_Right) ty2-                                          _                -> fail "not an unsafe coercion."-{-# INLINE unsafeCoT #-}---- | Rewrite all children of a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion-unsafeCoAllR r1 r2 = unsafeCoT r1 r2 UnsafeCo-{-# INLINE unsafeCoAllR #-}---- | Rewrite any children of a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion-unsafeCoAnyR r1 r2 = unwrapAnyR $ unsafeCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE unsafeCoAnyR #-}---- | Rewrite one child of a coercion of the form: @UnsafeCo@ 'Type' 'Type'-unsafeCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Type -> Rewrite c m Type -> Rewrite c m Coercion-unsafeCoOneR r1 r2 = unwrapOneR $ unsafeCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE unsafeCoOneR #-}----- | Translate a coercion of the form: @SymCo@ 'Coercion'-symCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion b -> Translate c m Coercion b-symCoT t = translate $ \ c -> \case-                                   SymCo co -> apply t (c @@ SymCo_Co) co-                                   _        -> fail "not a symmetric coercion."-{-# INLINE symCoT #-}---- | Rewrite the 'Coercion' child of a coercion of the form: @SymCo@ 'Coercion'-symCoR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion-symCoR r = symCoT (SymCo <$> r)-{-# INLINE symCoR #-}----- | Translate a coercion of the form: @TransCo@ 'Coercion' 'Coercion'-transCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-transCoT t1 t2 f = translate $ \ c -> \case-                                          TransCo co1 co2 -> f <$> apply t1 (c @@ TransCo_Left) co1 <*> apply t2 (c @@ TransCo_Right) co2-                                          _               -> fail "not a transitive coercion."-{-# INLINE transCoT #-}---- | Rewrite all children of a coercion of the form: @TransCo@ 'Coercion' 'Coercion'-transCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion-transCoAllR r1 r2 = transCoT r1 r2 TransCo-{-# INLINE transCoAllR #-}---- | Rewrite any children of a coercion of the form: @TransCo@ 'Coercion' 'Coercion'-transCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion-transCoAnyR r1 r2 = unwrapAnyR $ transCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE transCoAnyR #-}---- | Rewrite one child of a coercion of the form: @TransCo@ 'Coercion' 'Coercion'-transCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Coercion -> Rewrite c m Coercion-transCoOneR r1 r2 = unwrapOneR $ transCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE transCoOneR #-}----- | Translate a coercion of the form: @NthCo@ 'Int' 'Coercion'-nthCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Int a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-nthCoT t1 t2 f = translate $ \ c -> \case-                                          NthCo n co -> f <$> apply t1 (c @@ NthCo_Int) n <*> apply t2 (c @@ NthCo_Co) co-                                          _          -> fail "not an Nth coercion."-{-# INLINE nthCoT #-}---- | Rewrite all children of a coercion of the form: @NthCo@ 'Int' 'Coercion'-nthCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion-nthCoAllR r1 r2 = nthCoT r1 r2 NthCo-{-# INLINE nthCoAllR #-}---- | Rewrite any children of a coercion of the form: @NthCo@ 'Int' 'Coercion'-nthCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion-nthCoAnyR r1 r2 = unwrapAnyR $ nthCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE nthCoAnyR #-}---- | Rewrite one child of a coercion of the form: @NthCo@ 'Int' 'Coercion'-nthCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Int -> Rewrite c m Coercion -> Rewrite c m Coercion-nthCoOneR r1 r2 = unwrapOneR $ nthCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE nthCoOneR #-}---#if __GLASGOW_HASKELL__ > 706--- | Translate a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'-lrCoT :: (ExtendPath c Crumb, Monad m) => Translate c m LeftOrRight a1 -> Translate c m Coercion a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-lrCoT t1 t2 f = translate $ \ c -> \case-                                      LRCo lr co -> f <$> apply t1 (c @@ LRCo_LR) lr <*> apply t2 (c @@ LRCo_Co) co-                                      _          -> fail "not a left/right coercion."-{-# INLINE lrCoT #-}---- | Translate all children of a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'-lrCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion-lrCoAllR r1 r2 = lrCoT r1 r2 LRCo-{-# INLINE lrCoAllR #-}---- | Translate any children of a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'-lrCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion-lrCoAnyR r1 r2 = unwrapAnyR $ lrCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE lrCoAnyR #-}---- | Translate one child of a coercion of the form: @LRCo@ 'LeftOrRight' 'Coercion'-lrCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m LeftOrRight -> Rewrite c m Coercion -> Rewrite c m Coercion-lrCoOneR r1 r2 = unwrapOneR $ lrCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE lrCoOneR #-}-#else-#endif----- | Translate a coercion of the form: @InstCo@ 'Coercion' 'Type'-instCoT :: (ExtendPath c Crumb, Monad m) => Translate c m Coercion a1 -> Translate c m Type a2 -> (a1 -> a2 -> b) -> Translate c m Coercion b-instCoT t1 t2 f = translate $ \ c -> \case-                                          InstCo co ty -> f <$> apply t1 (c @@ InstCo_Co) co <*> apply t2 (c @@ InstCo_Type) ty-                                          _            -> fail "not a coercion instantiation."-{-# INLINE instCoT #-}---- | Rewrite all children of a coercion of the form: @InstCo@ 'Coercion' 'Type'-instCoAllR :: (ExtendPath c Crumb, Monad m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion-instCoAllR r1 r2 = instCoT r1 r2 InstCo-{-# INLINE instCoAllR #-}---- | Rewrite any children of a coercion of the form: @InstCo@ 'Coercion' 'Type'-instCoAnyR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion-instCoAnyR r1 r2 = unwrapAnyR $ instCoAllR (wrapAnyR r1) (wrapAnyR r2)-{-# INLINE instCoAnyR #-}---- | Rewrite one child of a coercion of the form: @InstCo@ 'Coercion' 'Type'-instCoOneR :: (ExtendPath c Crumb, MonadCatch m) => Rewrite c m Coercion -> Rewrite c m Type -> Rewrite c m Coercion-instCoOneR r1 r2 = unwrapOneR $ instCoAllR (wrapOneR r1) (wrapOneR r2)-{-# INLINE instCoOneR #-}------------------------------------------------------------------------------------------------------------------------------------------------- | Earlier versions of HERMIT used 'Int' as the crumb type.---   This translation maps an 'Int' to the corresponding 'Crumb', for backwards compatibility purposes.-deprecatedIntToCrumbT :: Monad m => Int -> Translate c m Core Crumb-deprecatedIntToCrumbT n = contextfreeT $ \case-                                            GutsCore _                 | n == 0                        -> return ModGuts_Prog-                                            AltCore _                  | n == 0                        -> return Alt_RHS-                                            DefCore _                  | n == 0                        -> return Def_RHS-                                            ProgCore (ProgCons _ _)    | n == 0                        -> return ProgCons_Head-                                                                       | n == 1                        -> return ProgCons_Tail-                                            BindCore (NonRec _ _)      | n == 0                        -> return NonRec_RHS-                                            BindCore (Rec bds)         | (n >= 0) && (n < length bds)  -> return (Rec_Def n)-                                            ExprCore (App _ _)         | n == 0                        -> return App_Fun-                                                                       | n == 1                        -> return App_Arg-                                            ExprCore (Lam _ _)         | n == 0                        -> return Lam_Body-                                            ExprCore (Let _ _)         | n == 0                        -> return Let_Bind-                                                                       | n == 1                        -> return Let_Body-                                            ExprCore (Case _ _ _ alts) | n == 0                        -> return Case_Scrutinee-                                                                       | (n > 0) && (n <= length alts) -> return (Case_Alt (n-1))-                                            ExprCore (Cast _ _)        | n == 0                        -> return Cast_Expr-                                            ExprCore (Tick _ _)        | n == 0                        -> return Tick_Expr-                                            _                                                          -> fail ("Child " ++ show n ++ " does not exist.")-{-# INLINE deprecatedIntToCrumbT #-}---- | Builds a path to the first child, based on the old numbering system.-deprecatedIntToPathT :: Monad m => Int -> Translate c m Core PathH-deprecatedIntToPathT =  liftM return . deprecatedIntToCrumbT-{-# INLINE deprecatedIntToPathT #-}---------------------------------------------------------------------------------------------------------------------------------------------
− src/Language/HERMIT/Kure/SumTypes.hs
@@ -1,255 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, InstanceSigs #-}--module Language.HERMIT.Kure.SumTypes-  ( -- * Sum Types-    Core(..)-  , TyCo(..)-  , CoreTC(..)-  )-where--import GhcPlugins--import Language.KURE.Injection--import Language.HERMIT.Core--------------------------------------------------------------------------- | Core is a sum type for use by KURE.  Core = ModGuts + CoreProg + CoreBind + CoreDef + CoreExpr + CoreAlt-data Core = GutsCore  ModGuts            -- ^ The module.-          | ProgCore  CoreProg           -- ^ A program (a telescope of top-level binding groups).-          | BindCore  CoreBind           -- ^ A binding group.-          | DefCore   CoreDef            -- ^ A recursive definition.-          | ExprCore  CoreExpr           -- ^ An expression.-          | AltCore   CoreAlt            -- ^ A case alternative.---- | TyCo is a sum type for use by KURE.  TyCo = Type + Coercion-data TyCo = TypeCore Type                -- ^ A type.-          | CoercionCore Coercion        -- ^ A coercion.---- | CoreTC is a sum type for use by KURE.  CoreTC = Core + TyCo-data CoreTC = Core Core-            | TyCo TyCo-------------------------------------------------------------------------instance Injection ModGuts Core where--  inject :: ModGuts -> Core-  inject = GutsCore-  {-# INLINE inject #-}--  project :: Core -> Maybe ModGuts-  project (GutsCore guts) = Just guts-  project _               = Nothing-  {-# INLINE project #-}---instance Injection CoreProg Core where--  inject :: CoreProg -> Core-  inject = ProgCore-  {-# INLINE inject #-}--  project :: Core -> Maybe CoreProg-  project (ProgCore bds) = Just bds-  project _              = Nothing-  {-# INLINE project #-}---instance Injection CoreBind Core where--  inject :: CoreBind -> Core-  inject = BindCore-  {-# INLINE inject #-}--  project :: Core -> Maybe CoreBind-  project (BindCore bnd)  = Just bnd-  project _               = Nothing-  {-# INLINE project #-}---instance Injection CoreDef Core where--  inject :: CoreDef -> Core-  inject = DefCore-  {-# INLINE inject #-}--  project :: Core -> Maybe CoreDef-  project (DefCore def) = Just def-  project _             = Nothing-  {-# INLINE project #-}---instance Injection CoreAlt Core where--  inject :: CoreAlt -> Core-  inject = AltCore-  {-# INLINE inject #-}--  project :: Core -> Maybe CoreAlt-  project (AltCore expr) = Just expr-  project _              = Nothing-  {-# INLINE project #-}---instance Injection CoreExpr Core where--  inject :: CoreExpr -> Core-  inject = ExprCore-  {-# INLINE inject #-}--  project :: Core -> Maybe CoreExpr-  project (ExprCore expr) = Just expr-  project _               = Nothing-  {-# INLINE project #-}-------------------------------------------------------------------------instance Injection Type TyCo where--  inject :: Type -> TyCo-  inject = TypeCore-  {-# INLINE inject #-}--  project :: TyCo -> Maybe Type-  project (TypeCore ty) = Just ty-  project _             = Nothing-  {-# INLINE project #-}---instance Injection Coercion TyCo where--  inject :: Coercion -> TyCo-  inject = CoercionCore-  {-# INLINE inject #-}--  project :: TyCo -> Maybe Coercion-  project (CoercionCore ty) = Just ty-  project _                 = Nothing-  {-# INLINE project #-}-------------------------------------------------------------------------instance Injection Core CoreTC where--  inject :: Core -> CoreTC-  inject = Core-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe Core-  project (Core core) = Just core-  project _           = Nothing-  {-# INLINE project #-}---instance Injection TyCo CoreTC where--  inject :: TyCo -> CoreTC-  inject = TyCo-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe TyCo-  project (TyCo tyCo) = Just tyCo-  project _           = Nothing-  {-# INLINE project #-}-------------------------------------------------------------------------instance Injection ModGuts CoreTC where--  inject :: ModGuts -> CoreTC-  inject = Core . GutsCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe ModGuts-  project (Core (GutsCore guts)) = Just guts-  project _                      = Nothing-  {-# INLINE project #-}---instance Injection CoreProg CoreTC where--  inject :: CoreProg -> CoreTC-  inject = Core . ProgCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe CoreProg-  project (Core (ProgCore bds)) = Just bds-  project _                     = Nothing-  {-# INLINE project #-}---instance Injection CoreBind CoreTC where--  inject :: CoreBind -> CoreTC-  inject = Core . BindCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe CoreBind-  project (Core (BindCore bnd))  = Just bnd-  project _                      = Nothing-  {-# INLINE project #-}---instance Injection CoreDef CoreTC where--  inject :: CoreDef -> CoreTC-  inject = Core . DefCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe CoreDef-  project (Core (DefCore def)) = Just def-  project _                    = Nothing-  {-# INLINE project #-}---instance Injection CoreAlt CoreTC where--  inject :: CoreAlt -> CoreTC-  inject = Core . AltCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe CoreAlt-  project (Core (AltCore expr)) = Just expr-  project _                     = Nothing-  {-# INLINE project #-}---instance Injection CoreExpr CoreTC where--  inject :: CoreExpr -> CoreTC-  inject = Core . ExprCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe CoreExpr-  project (Core (ExprCore expr)) = Just expr-  project _                      = Nothing-  {-# INLINE project #-}---instance Injection Type CoreTC where--  inject :: Type -> CoreTC-  inject = TyCo . TypeCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe Type-  project (TyCo (TypeCore ty)) = Just ty-  project _                    = Nothing-  {-# INLINE project #-}---instance Injection Coercion CoreTC where--  inject :: Coercion -> CoreTC-  inject = TyCo . CoercionCore-  {-# INLINE inject #-}--  project :: CoreTC -> Maybe Coercion-  project (TyCo (CoercionCore ty)) = Just ty-  project _                        = Nothing-  {-# INLINE project #-}-----------------------------------------------------------------------
− src/Language/HERMIT/Monad.hs
@@ -1,171 +0,0 @@-{-# LANGUAGE InstanceSigs #-}--module Language.HERMIT.Monad-          (-            -- * The HERMIT Monad-            HermitM-          , runHM-          , liftCoreM-          , newIdH-          , newTyVarH-    --      , newVarExprH-    --      , newVarH-          , cloneVarH-            -- * Saving Definitions-          , Label-          , DefStash-          , saveDef-          , lookupDef-          , getStash-            -- * Messages-          , HermitMEnv(..)-          , DebugMessage(..)-          , mkHermitMEnv-          , sendDebugMessage-) where--import Prelude hiding (lookup)--import Data.Map--import GhcPlugins hiding (empty)-import MonadUtils       -- from GHC--import Control.Monad-import Control.Arrow--import Language.KURE--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure.SumTypes---------------------------------------------------------------------------------- | A label for individual definitions.-type Label = String---- | A store of saved definitions.-type DefStash = Map Label CoreDef---- | A way of sending messages to top level-newtype HermitMEnv = HermitMEnv { hs_debugChan :: DebugMessage -> HermitM () }---- | The HERMIT monad is kept abstract.-newtype HermitM a = HermitM (HermitMEnv -> DefStash -> CoreM (KureM (DefStash, a)))--runHermitM :: HermitM a -> HermitMEnv -> DefStash -> CoreM (KureM (DefStash, a))-runHermitM (HermitM f) = f---- | Get the stash of saved definitions.-getStash :: HermitM DefStash-getStash = HermitM (\ _ s -> return $ return (s, s))---- | Replace the stash of saved definitions.-putStash :: DefStash -> HermitM ()-putStash s = HermitM (\ _ _ -> return $ return (s, ()))--sendDebugMessage :: DebugMessage -> HermitM ()-sendDebugMessage msg = do env <- HermitM $ \ ch s -> return $ return (s, ch)-                          hs_debugChan env msg---- | Save a definition for future use.-saveDef :: Label -> CoreDef -> HermitM ()-saveDef l d = getStash >>= (insert l d >>> putStash)---- | Lookup a previously saved definition.-lookupDef :: Label -> HermitM CoreDef-lookupDef l = getStash >>= (lookup l >>> maybe (fail "Definition not found.") return)---- | Eliminator for 'HermitM'.-runHM :: HermitMEnv -> DefStash -> (DefStash -> a -> CoreM b) -> (String -> CoreM b) -> HermitM a -> CoreM b-runHM env s success failure ma = runHermitM ma env s >>= runKureM (\ (a,b) -> success a b) failure--------------------------------------------------------------------------------instance Functor HermitM where-  fmap :: (a -> b) -> HermitM a -> HermitM b-  fmap = liftM--instance Applicative HermitM where-  pure :: a -> HermitM a-  pure = return--  (<*>) :: HermitM (a -> b) -> HermitM a -> HermitM b-  (<*>) = ap--instance Monad HermitM where-  return :: a -> HermitM a-  return a = HermitM $ \ _ s -> return (return (s,a))--  (>>=) :: HermitM a -> (a -> HermitM b) -> HermitM b-  (HermitM gcm) >>= f = HermitM $ \ env -> gcm env >=> runKureM (\ (s', a) -> runHermitM (f a) env s') (return . fail)--  fail :: String -> HermitM a-  fail msg = HermitM $ \ _ _ -> return (fail msg)--instance MonadCatch HermitM where-  catchM :: HermitM a -> (String -> HermitM a) -> HermitM a-  (HermitM gcm) `catchM` f = HermitM $ \ env s -> gcm env s >>= runKureM (return.return) (\ msg -> runHermitM (f msg) env s)---------------------------------------------------------------------------------- | 'CoreM' can be lifted to 'HermitM'.-liftCoreM :: CoreM a -> HermitM a-liftCoreM ma = HermitM $ \ _ s -> do a <- ma-                                     return (return (s,a))--instance MonadIO HermitM where-  liftIO :: IO a -> HermitM a-  liftIO = liftCoreM . liftIO--instance MonadUnique HermitM where-  getUniqueSupplyM :: HermitM UniqSupply-  getUniqueSupplyM = liftCoreM getUniqueSupplyM--instance MonadThings HermitM where-  lookupThing :: Name -> HermitM TyThing-  lookupThing = liftCoreM . lookupThing--instance HasDynFlags HermitM where-  getDynFlags :: HermitM DynFlags-  getDynFlags = liftCoreM getDynFlags--------------------------------------------------------------------------------newName :: String -> HermitM Name-newName name = do uq <- getUniqueM-                  return $ mkSystemVarName uq $ mkFastString name---- | Make a unique identifier for a specified type based on a provided name.-newIdH :: String -> Type -> HermitM Id-newIdH name ty = do name' <- newName name-                    return $ mkLocalId name' ty---- | Make a unique type variable for a specified kind based on a provided name.-newTyVarH :: String -> Kind -> HermitM TyVar-newTyVarH name kind = do name' <- newName name-                         return $ mkTyVar name' kind---- | This gives an new version of a 'Var', with the same info, and a new textual name.-cloneVarH :: (String -> String) -> Var -> HermitM Var-cloneVarH nameMod v =-        let name = nameMod (getOccString v)-            ty   = varType v-        in-          if isTyVar v-           then newTyVarH name ty-           else newIdH name ty---------------------------------------------------------------------------------- | A message packet.-data DebugMessage  =  DebugTick String-                   |  DebugCore String HermitC Core    -- ^ A postcard.--mkHermitMEnv :: (DebugMessage -> HermitM ()) -> HermitMEnv-mkHermitMEnv debugger = HermitMEnv-                { hs_debugChan = debugger-                }------------------------------------------------------------------------------
− src/Language/HERMIT/Optimize.hs
@@ -1,158 +0,0 @@-{-# LANGUAGE KindSignatures, GADTs, FlexibleContexts #-}-module Language.HERMIT.Optimize-    ( -- * The HERMIT Plugin-      optimize-      -- ** Running translations-    , query-    , run-      -- ** Using the shell-    , interactive-    , display-    , setPretty-    , setPrettyOptions-      -- ** Active modifiers-    , at-    , phase-    , after-    , before-    , allPhases-    , firstPhase-    , lastPhase-    ) where--import GhcPlugins hiding (singleton, liftIO, display)-import qualified GhcPlugins as GHC--import Control.Monad.Operational-import Control.Monad.State hiding (guard)--import Data.Default--import Language.HERMIT.Dictionary-import Language.HERMIT.External hiding (Query, Shell)-import Language.HERMIT.Kernel.Scoped-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.Monad-import Language.HERMIT.Plugin-import Language.HERMIT.PrettyPrinter.Common-import qualified Language.HERMIT.PrettyPrinter.Clean as Clean-import Language.HERMIT.Shell.Command--import System.Console.Haskeline (defaultBehavior)-import System.IO (stdout)--data OInst :: * -> * where-    Shell    :: [External] -> [CommandLineOption] -> OInst ()-    Guard    :: (PhaseInfo -> Bool) -> OM ()      -> OInst ()-    -- with some refactoring of the interpreter I'm pretty sure-    -- we can make Focus polymorphic-    Focus    :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g PathH -> OM () -> OInst ()-    RR       :: (Injection GHC.ModGuts g, Walker HermitC g) => RewriteH g                  -> OInst ()-    Query    :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g a              -> OInst a---- using operational, but would we nice to use Neil's constrained-normal package!-type OM a = ProgramT OInst (StateT InterpState IO) a--optimize :: ([CommandLineOption] -> OM ()) -> Plugin-optimize f = hermitPlugin $ \ phaseInfo -> runOM phaseInfo . f--data InterpState =-    InterpState { isAST :: SAST-                , isPretty :: PrettyOptions -> PrettyH CoreTC-                , isPrettyOptions :: PrettyOptions-                -- TODO: remove once shell can return-                , shellHack :: Maybe ([External], [CommandLineOption])-                }-type InterpM a = StateT InterpState IO a--runOM :: PhaseInfo -> OM () -> ModGuts -> CoreM ModGuts-runOM phaseInfo opt = scopedKernel $ \ kernel initSAST ->-    let env = mkHermitMEnv $ GHC.liftIO . debug-        debug (DebugTick msg) = putStrLn msg-        debug (DebugCore msg _c _e) = putStrLn $ "Core: " ++ msg--        errorAbortIO err = putStrLn err >> abortS kernel-        errorAbort = liftIO . errorAbortIO--        initState = InterpState initSAST Clean.corePrettyH def Nothing--        eval :: PathH -> ProgramT OInst (StateT InterpState IO) () -> InterpM ()-        eval path comp = do-            sast <- gets isAST-            v <- viewT comp-            case v of-                Return _            -> return ()-                RR rr       :>>= k  -> liftIO (applyS kernel sast (pathR path rr) env)-                                        >>= runKureM (\sast' -> modify (\s -> s { isAST = sast' }))-                                                     errorAbort >> eval path (k ())-                Query tr    :>>= k  -> liftIO (queryS kernel sast (pathT path tr) env)-                                        >>= runKureM (eval path . k) errorAbort-                -- TODO: rework shell so it can return to k-                --       this will significantly simplify this code-                --       as we can just call the shell directly here-                Shell es os :>>= _k -> modify (\s -> s { shellHack = Just (es,os) })-                                       -- liftIO $ Shell.interactive os defaultBehavior es kernel sast-                                       -- calling the shell directly causes indefinite MVar problems-                                       -- because the state monad never finishes (I think)-                Guard p m   :>>= k  -> when (p phaseInfo) (eval path m) >> eval path (k ())-                Focus tp m  :>>= k  -> liftIO (queryS kernel sast tp env)-                                        >>= runKureM (flip eval m) errorAbort >> eval path (k ())--    in do st <- execStateT (eval [] opt) initState-          let sast = isAST st-          maybe (liftIO (resumeS kernel sast) >>= runKureM return errorAbortIO)-                (\(es,os) -> liftIO $ commandLine os defaultBehavior es kernel sast)-                (shellHack st)--interactive :: [External] -> [CommandLineOption] -> OM ()-interactive es os = singleton $ Shell (externals ++ es) os--run :: RewriteH Core -> OM ()-run = singleton . RR--query :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g a -> OM a-query = singleton . Query------------------------------- guards --------------------------------guard :: (PhaseInfo -> Bool) -> OM () -> OM ()-guard p = singleton . Guard p--at :: TranslateH Core PathH -> OM () -> OM ()-at tp = singleton . Focus tp--phase :: Int -> OM () -> OM ()-phase n = guard ((n ==) . phaseNum)--after :: CorePass -> OM () -> OM ()-after cp = guard (\phaseInfo -> case phasesDone phaseInfo of-                            [] -> False-                            xs -> last xs == cp)--before :: CorePass -> OM () -> OM ()-before cp = guard (\phaseInfo -> case phasesLeft phaseInfo of-                            (x:_) | cp == x -> True-                            _               -> False)--allPhases :: OM () -> OM ()-allPhases = guard (const True)--firstPhase :: OM () -> OM ()-firstPhase = guard (null . phasesDone)--lastPhase :: OM () -> OM ()-lastPhase = guard (null . phasesLeft)------------------------------- other --------------------------------display :: OM ()-display = do-    po <- gets isPrettyOptions-    gets isPretty >>= query . liftPrettyH . ($ po) >>= liftIO . unicodeConsole stdout po--setPretty :: (PrettyOptions -> PrettyH CoreTC) -> OM ()-setPretty pp = modify $ \s -> s { isPretty = pp }--setPrettyOptions :: PrettyOptions -> OM ()-setPrettyOptions po = modify $ \s -> s { isPrettyOptions = po }
− src/Language/HERMIT/Parser.y
@@ -1,189 +0,0 @@-{-module Language.HERMIT.Parser-    ( parseStmtsH-    , unparseExprH-    , numStmtsH-    , ExprH(..)-    ) where--import Data.Char (isSpace)-import Data.List (intercalate)--import Language.HERMIT.Syntax (isScriptInfixIdChar, isScriptIdFirstChar, isScriptIdChar)--}--%name parser-%tokentype { Token }-%error { parseError }-%monad { Either String } { >>= } { return }--%token-    '('     { ParenLeft }-    ')'     { ParenRight }-    '{'     { ScopeStart }-    '}'     { ScopeEnd }-    '['     { ListStart }-    ','     { ListDelim }-    ']'     { ListEnd }-    ';'     { StmtEnd }-    '\''    { Tick }-    core    { CoreString $$ }-    quoted  { Quote $$ }-    ident   { Ident $$ }-    infixop { InfixOp $$ }--%%--scoped : '{' scoped { CmdName "{" : $2 }-       | '}' scoped { CmdName "}" : $2 }-       | slist      { $1 }--slist : stmts       { $1 }-      | {- empty -} { [] }---- | Be really liberal about where ';' can be!---   Recall that newlines are lexed as ';'-stmts : ExprH            { [$1] }-      | ExprH '}' scoped { [$1, CmdName "}"] ++ $3 }-      | ExprH ';' scoped { $1 : $3 }-      | ';' scoped       { $2 }---- | Top level expression term.---   Infix operators bind less tightly than application.-ExprH : e2 infixop ExprH   { AppH (AppH (CmdName $2) $1) $3 }-      | e2                 { $1 }---- | Expressions without infix operators in them.-e2   : e2 arg          { AppH $1 $2 }-     | arg             { $1 }---- | Expressions that can be arguments in an application.-arg  : '\'' ident      { SrcName $2 }-     | '\'' infixop    { SrcName $2 }-     | '\'' quoted     { SrcName $2 }-     | quoted          { CmdName $1 }-     | core            { CoreH $1 }-     | '[' elist ']'   { ListH $2 }-     | '(' ExprH ')'   { $2 }-     | ident           { CmdName $1 }--elist : exprs       { $1 }-      | {- empty -} { [] }--exprs : ExprH           { [$1] }-      | ExprH ',' exprs { $1 : $3 }-{--parseError :: [Token] -> Either String a-parseError ts = Left $ "parse error: " ++ show ts---- | A simple expression language AST, for things parsed from 'String' or JSON structures.-data ExprH-    = SrcName String                -- ^ Variable names (refers to source code).-    | CmdName String                -- ^ Commands (to be looked up in 'Language.HERMIT.Dictionary').-    | AppH ExprH ExprH              -- ^ Application.-    | CoreH String                  -- ^ Core Fragment-    | ListH [ExprH]                 -- ^ List of expressions-    deriving (Eq, Show)--data Token-    = ParenLeft-    | ParenRight-    | ScopeStart-    | ScopeEnd-    | ListStart-    | ListDelim-    | ListEnd-    | StmtEnd-    | Tick-    | CoreString String-    | Quote String-    | Ident String-    | InfixOp String-    deriving (Eq, Show)--lexer :: String -> Either String [Token]-lexer []           = Right []-lexer ('\n':cs)    = fmap (StmtEnd:)    $ lexer cs-lexer (';' :cs)    = fmap (StmtEnd:)    $ lexer cs-lexer ('(' :cs)    = fmap (ParenLeft:)  $ lexer cs-lexer (')' :cs)    = fmap (ParenRight:) $ lexer cs-lexer ('{' :cs)    = fmap (ScopeStart:) $ lexer cs-lexer ('}' :cs)    = fmap (ScopeEnd:)   $ lexer cs-lexer ('\'':cs)    = fmap (Tick:)       $ lexer cs-lexer ('\"':cs)    = do (str,cs') <- lexString cs-                        fmap (Quote str:) $ lexer cs'-lexer ('[':'|':cs) = do (str,cs') <- lexCore cs-                        fmap (CoreString str:) $ lexer cs'-lexer ('-':'-':cs) = let (_,s') = span (/= '\n') cs in lexer s'-lexer ('[' :cs)    = fmap (ListStart:)  $ lexer cs-lexer (',' :cs)    = fmap (ListDelim:)  $ lexer cs-lexer (']' :cs)    = fmap (ListEnd:)    $ lexer cs-lexer s@(c:cs)     | isSpace             c = lexer cs-                   | isScriptIdFirstChar c = let (i,s') = span isScriptIdChar s-                                              in fmap (Ident i:) $ lexer s'-                   | isScriptInfixIdChar c = let (op,s') = span isScriptInfixIdChar s-                                              in fmap (InfixOp op:) $ lexer s'-lexer s            = Left $ "lexer: no match on " ++ s--lexString :: String -> Either String (String,String)-lexString ('\"':cs)      = Right ([],cs)-lexString ('\\':'\"':cs) = do (c',r) <- lexString cs-                              return ('"':c',r)-lexString (c:cs)         = do (c',r) <- lexString cs-                              return (c:c',r)-lexString []             = Left "lexer: no matching quote"--lexCore :: String -> Either String (String,String)-lexCore ('|':']':rest) = Right ([],rest)-lexCore (c:cs)         = do (c',r) <- lexCore cs-                            return (c:c',r)-lexCore []             = Left "lexer: no closing |]"--------------------------------------------------- | Use ghci Parser.hs to run this test function.-test = do-    ln <- getLine-    case ln of-        "quit" -> return ()-        _      -> do print $ lexer ln-                     print $ parseStmtsH ln-                     test--parseStmtsH :: String -> Either String [ExprH]-parseStmtsH s = lexer s >>= parser--numStmtsH :: [ExprH] -> Int-numStmtsH = length . filter isCounted-    where isCounted (CmdName "{") = False-          isCounted (CmdName "}") = False-          isCounted _             = True------------------------------------------------unparseExprH :: ExprH -> String-unparseExprH (SrcName nm)-    | nm /= "" && (all isScriptInfixIdChar nm || isScriptIdFirstChar (head nm) && all isScriptIdChar (tail nm)) = "'" ++ nm-    | otherwise = "'\"" ++ concatMap escape nm ++ "\""-        where escape '\"' = "\\\""-              escape c    = [c]-unparseExprH (CmdName nm)-    | nm == "{"             = "{ "-    | nm == "}"             = " }"-    | all isScriptIdChar nm = nm-    | otherwise             = show nm     -- with quotes-unparseExprH (AppH (AppH (CmdName nm) e1) e2)-    | all isScriptInfixIdChar nm-    = unparseAtom e1 ++ " " ++ nm ++ " " ++ unparseAtom e2-unparseExprH (AppH e1 e2) = unparseExprH e1 ++ " " ++ unparseAtom e2-unparseExprH (CoreH s)    = "[|" ++ s ++ "|]"-unparseExprH (ListH es)   = "[" ++ intercalate "," (map unparseExprH es) ++ "]"--unparseAtom :: ExprH -> String-unparseAtom e@(AppH {}) = "(" ++ unparseExprH e ++ ")"-unparseAtom e           = unparseExprH e-------------------------------------------------}
− src/Language/HERMIT/ParserCore.y
@@ -1,167 +0,0 @@-{-{-# LANGUAGE CPP #-}-module Language.HERMIT.ParserCore (parseCore) where--import Control.Monad.Reader-import Data.Char (isSpace, isDigit)--import GhcPlugins--import Language.HERMIT.Context-import Language.HERMIT.External-import Language.HERMIT.Monad-import Language.HERMIT.Primitive.Common-import Language.HERMIT.Syntax (isCoreInfixIdChar, isCoreIdFirstChar, isCoreIdChar)--import Language.KURE.MonadCatch (prefixFailMsg)--import Language.Haskell.TH as TH-}--%name parser-%tokentype { Token }-%error { parseError }-%monad { CoreParseM } { >>= } { return }--%token-    '%forall'  { Tforall }-    '%rec'     { Trec }-    '%let'     { Tlet }-    '%in'      { Tin }-    '%case'    { Tcase }-    '%of'      { Tof }-    '%cast'    { Tcast }-    '%note'    { Tnote }-    '%external'    { Texternal }-    '%local'   { Tlocal }-    '%_'       { Twild }-    '('        { Toparen }-    ')'        { Tcparen }-    '{'        { Tobrace }-    '}'        { Tcbrace }-    '#'        { Thash}-    '='        { Teq }-    ':'        { Tcolon }-    '::'       { Tcoloncolon }-    ':=:'      { Tcoloneqcolon }-    '*'        { Tstar }-    '->'       { Tarrow }-    '\\'       { Tlambda}-    '@'        { Tat }-    '.'        { Tdot }-    '?'        { Tquestion}-    ';'            { Tsemicolon }-    NAME       { Tname $$ }-    CNAME      { Tcname $$ }-    INTEGER    { Tinteger $$ }-    RATIONAL   { Trational $$ }-    STRING     { Tstring $$ }-    CHAR       { Tchar $$ }--%%---- | Top level expression term.-expr : app             { $1 }--app : app arg          { App $1 $2 }-    | arg              { $1 }--arg : '(' expr ')'     { $2 }-    | '(' ')'          {% lookupName "()" Var }-    | var              { $1 }-    | intlit           { $1 }-    | strlit           { $1 }--intlit : INTEGER       {% mkIntExpr' $1 } -- mkIntLit makes a primitive Int#--strlit : STRING        {% lift $ mkStringExpr $1 }--var : NAME             {% lookupName $1 varToCoreExpr }-{--mkIntExpr' :: Integer -> CoreParseM CoreExpr-#if __GLASGOW_HASKELL__ > 706-mkIntExpr' i = do-    dflags <- lift getDynFlags-    return $ mkIntExpr dflags i-#else-mkIntExpr' i = return $ mkIntExpr i-#endif--lookupName :: String -> (Id -> CoreExpr) -> CoreParseM CoreExpr-lookupName nm k = do-    c <- ask-    v <- lift $ prefixFailMsg (nm ++ " lookup: ") $ findId (TH.mkName nm) c-    return (k v)--type CoreParseM a = ReaderT HermitC HermitM a--parseError :: Monad m => [Token] -> m a-parseError ts = fail $ "core parse error: " ++ show ts--data Token-    = Tforall-    | Trec-    | Tlet-    | Tin-    | Tcase-    | Tof-    | Tcast-    | Tnote-    | Texternal-    | Tlocal-    | Twild ---    | Toparen ---    | Tcparen ---    | Tobrace-    | Tcbrace-    | Thash-    | Teq-    | Tcolon ---    | Tcoloncolon ---    | Tcoloneqcolon-    | Tstar-    | Tarrow-    | Tlambda ---    | Tat-    | Tdot-    | Tquestion-    | Tsemicolon-    | Tname String-    | Tcname String-    | Tinteger Integer-    | Trational Float-    | Tstring String-    | Tchar Char-    deriving (Eq, Show)--lexer :: String -> Either String [Token]-lexer []           = Right []-lexer ('_' :cs)    = fmap (Twild:)       $ lexer cs-lexer ('(' :cs)    = fmap (Toparen:)     $ lexer cs-lexer (')' :cs)    = fmap (Tcparen:)     $ lexer cs-lexer (':':':':cs) = fmap (Tcoloncolon:) $ lexer cs--- lexer (':' :cs)    = fmap (Tcolon:)      $ lexer cs-lexer ('\\':cs)    = fmap (Tlambda:)     $ lexer cs-lexer ('-':'>':cs) = fmap (Tarrow:)      $ lexer cs-lexer ('\"':cs)    = let (str,rest) = span (/='\"') cs-                     in case rest of-                           ('\"':cs') -> fmap (Tstring str:) $ lexer cs'-                           _          -> Left "lexer: no matching quote"-lexer s@(c:cs) | isSpace           c = lexer cs-               | isDigit           c = let (i,s') = span isDigit s-                                         in fmap (Tinteger (read i):) $ lexer s'-               | isCoreIdFirstChar c = let (i,s') = span isCoreIdChar s-                                         in fmap (Tname i:) $ lexer s'-               | isCoreInfixIdChar c = let (op,s') = span isCoreInfixIdChar s-                                         in fmap (Tname op:) $ lexer s'-lexer s            = Left $ "lexer: no match on " ++ s-------------------------------------------------parseCore :: CoreString -> HermitC -> HermitM CoreExpr-parseCore (CoreString s) c =-    case lexer s of-        Left msg -> fail msg-        Right tokens -> runReaderT (parser tokens) c-}
− src/Language/HERMIT/Plugin.hs
@@ -1,127 +0,0 @@-module Language.HERMIT.Plugin-    ( -- * The HERMIT Plugin-      HermitPass-    , hermitPlugin-    , CorePass(..)-    , getCorePass-    , ghcPasses-    , PhaseInfo(..)-    )  where--import GhcPlugins-import Data.List-import System.IO---- | Given a list of 'CommandLineOption's, produce the 'ModGuts' to 'ModGuts' function required to build a plugin.-type HermitPass = PhaseInfo -> [CommandLineOption] -> ModGuts -> CoreM ModGuts---- | Build a hermit plugin. This mainly handles the per-module options.-hermitPlugin :: HermitPass -> Plugin-hermitPlugin hp = defaultPlugin { installCoreToDos = install }-    where-        install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]-        install opts todos = do-            reinitializeGlobals--            -- This is a bit of a hack; otherwise we lose what we've not seen-            liftIO $ hSetBuffering stdout NoBuffering--            let (m_opts, _h_opts) = partition (isInfixOf ":") opts-                passes = map getCorePass todos-                allPasses = foldr (\ (n,p,seen,notyet) r -> mkPass n seen notyet : p : r)-                                  [mkPass (length todos) passes []]-                                  (zip4 [0..] todos (inits passes) (tails passes))-                mkPass n ps ps' = CoreDoPluginPass ("HERMIT" ++ show n) $ modFilter hp (PhaseInfo n ps ps') m_opts--            return allPasses---- | Determine whether to act on this module, choose plugin pass.--- NB: we have the ability to stick module info in the phase info here-modFilter :: HermitPass -> HermitPass-modFilter hp pInfo opts guts -    | null modOpts && not (null opts) = return guts -- don't process this module-    | otherwise                       = hp pInfo (filter (not . null) modOpts) guts-    where modOpts = filterOpts opts guts---- | Filter options to those pertaining to this module, stripping module prefix.-filterOpts :: [CommandLineOption] -> ModGuts -> [CommandLineOption]-filterOpts opts guts = [ drop len nm | nm <- opts, modName `isPrefixOf` nm ]-    where modName = moduleNameString $ moduleName $ mg_module guts-          len = length modName + 1 -- for the colon--data CorePass = FloatInwards-              | LiberateCase-              | PrintCore-              | StaticArgs-              | Strictness-              | WorkerWrapper-              | Specialising-              | SpecConstr-              | CSE-              | Vectorisation-              | Desugar-              | DesugarOpt-              | Tidy-              | Prep-              | Simplify-              | FloatOutwards-              | RuleCheck-              | Passes -- these should be flattened out in practice-              | PluginPass String-              | NoOp-              | Unknown-    deriving (Read, Show, Eq)--ghcPasses :: [(CorePass, CoreToDo)]-ghcPasses = [ (FloatInwards , CoreDoFloatInwards)-            , (LiberateCase , CoreLiberateCase)-            , (PrintCore    , CoreDoPrintCore)-            , (StaticArgs   , CoreDoStaticArgs)-            , (Strictness   , CoreDoStrictness)-            , (WorkerWrapper, CoreDoWorkerWrapper)-            , (Specialising , CoreDoSpecialising)-            , (SpecConstr   , CoreDoSpecConstr)-            , (CSE          , CoreCSE)-            , (Vectorisation, CoreDoVectorisation)-            , (Desugar      , CoreDesugar)    -- Right after desugaring, no simple optimisation yet!-            , (DesugarOpt   , CoreDesugarOpt) -- CoreDesugarXXX: Not strictly a core-to-core pass, but produces-            , (Tidy         , CoreTidy)-            , (Prep         , CorePrep)-            , (NoOp         , CoreDoNothing)-            ]---- The following are not allowed yet because they required options.--- CoreDoSimplify {- The core-to-core simplifier. -} Int {- Max iterations -} SimplifierMode--- CoreDoFloatOutwards FloatOutSwitches--- CoreDoRuleCheck CompilerPhase String   -- Check for non-application of rules matching this string--- CoreDoPasses [CoreToDo]                -- lists of these things--getCorePass :: CoreToDo -> CorePass-getCorePass CoreDoFloatInwards  = FloatInwards-getCorePass CoreLiberateCase    = LiberateCase-getCorePass CoreDoPrintCore     = PrintCore-getCorePass CoreDoStaticArgs    = StaticArgs-getCorePass CoreDoStrictness    = Strictness-getCorePass CoreDoWorkerWrapper = WorkerWrapper-getCorePass CoreDoSpecialising  = Specialising-getCorePass CoreDoSpecConstr    = SpecConstr-getCorePass CoreCSE             = CSE-getCorePass CoreDoVectorisation = Vectorisation-getCorePass CoreDesugar         = Desugar-getCorePass CoreDesugarOpt      = DesugarOpt-getCorePass CoreTidy            = Tidy-getCorePass CorePrep            = Prep-getCorePass (CoreDoSimplify {}) = Simplify-getCorePass (CoreDoFloatOutwards {}) = FloatOutwards-getCorePass (CoreDoRuleCheck {}) = RuleCheck-getCorePass (CoreDoPasses {})   = Passes -- these should be flattened out in practice-getCorePass (CoreDoPluginPass nm _) = PluginPass nm-getCorePass CoreDoNothing       = NoOp--- getCorePass _                   = Unknown--data PhaseInfo = -    PhaseInfo { phaseNum :: Int-              , phasesDone :: [CorePass]-              , phasesLeft :: [CorePass]-              }-    deriving (Read, Show, Eq)
− src/Language/HERMIT/PrettyPrinter/AST.hs
@@ -1,112 +0,0 @@-{-# LANGUAGE CPP #-}---- | Output the raw Expr constructors. Helpful for writing pattern matching rewrites.-module Language.HERMIT.PrettyPrinter.AST-  ( -- * HERMIT's AST Pretty-Printer for GHC Core-    corePrettyH-  )-where--import Control.Arrow hiding ((<+>))--import Data.Char (isSpace)--import GhcPlugins (Coercion(..), Var(..))-import qualified GhcPlugins as GHC--import Language.HERMIT.GHC-import Language.HERMIT.Kure-import Language.HERMIT.Core-import Language.HERMIT.PrettyPrinter.Common--import Text.PrettyPrint.MarkedHughesPJ as PP--------------------------------------------------------------------------------- | Pretty print a fragment of GHC Core using HERMIT's \"AST\" pretty printer.---   This displays the tree of constructors using nested indentation.-corePrettyH :: PrettyOptions -> PrettyH CoreTC-corePrettyH opts = do-    dynFlags <- constT GHC.getDynFlags--    let hideNotes = po_notes opts--        -- Use for any GHC structure, the 'showSDoc' prefix is to remind us-        -- that we are eliding infomation here.-        ppSDoc :: (GHC.Outputable a) => a -> MDoc b-        ppSDoc = toDoc . (if hideNotes then id else ("showSDoc: " ++)) . GHC.showSDoc dynFlags . GHC.ppr-            where toDoc s | any isSpace s = parens (text s)-                          | otherwise     = text s--        ppModGuts :: PrettyH GHC.ModGuts-        ppModGuts = arr (ppSDoc . GHC.mg_module)--        ppCoreProg :: PrettyH CoreProg-        ppCoreProg = progConsT ppCoreBind ppCoreProg ($+$) <+ progNilT empty--        ppCoreExpr :: PrettyH GHC.CoreExpr-        ppCoreExpr = varT (ppVar >>^ \ i -> text "Var" <+> i)-                  <+ litT (arr $ \ x -> text "Lit" <+> ppSDoc x)-                  <+ appT ppCoreExpr ppCoreExpr (\ a b -> text "App" $$ nest 2 (cat [parens a, parens b]))-                  <+ lamT ppVar ppCoreExpr (\ v e -> text "Lam" <+> v $$ nest 2 (parens e))-                  <+ letT ppCoreBind ppCoreExpr (\ b e -> text "Let" $$ nest 2 (cat [parens b, parens e]))-                  <+ caseT ppCoreExpr ppVar ppType (const ppCoreAlt) (\s w ty alts ->-                            text "Case" $$ nest 2 (parens s) $$ nest 2 w $$ nest 2 (parens ty) $$ nest 2 (vlist alts))-                  <+ castT ppCoreExpr ppCoercion (\ e co -> text "Cast" $$ nest 2 (cat [parens e, parens co]))-                  <+ tickT (arr ppSDoc) ppCoreExpr (\ tk e  -> text "Tick" $$ nest 2 (tk <+> parens e))-                  <+ typeT (ppType >>^ \ ty -> text "Type" $$ nest 2 (parens ty))-                  <+ coercionT (ppCoercion >>^ \ co -> text "Coercion" $$ nest 2 (parens co))--        ppCoreBind :: PrettyH GHC.CoreBind-        ppCoreBind = nonRecT ppVar ppCoreExpr (\ v e -> text "NonRec" <+> v $$ nest 2 (parens e))-                  <+ recT (const ppCoreDef) (\ bnds -> text "Rec" $$ nest 2 (vlist bnds))--        ppCoreAlt :: PrettyH GHC.CoreAlt-        ppCoreAlt = altT (arr ppSDoc) (\ _ -> ppVar) ppCoreExpr $ \ con vs e -> text "Alt" <+> con <+> hlist vs $$ nest 2 (parens e)--        ppCoreDef :: PrettyH CoreDef-        ppCoreDef = defT ppVar ppCoreExpr (\ i e -> text "Def" <+> i $$ nest 2 (parens e))--        ppType :: PrettyH Type-        ppType =  tyVarT (ppVar >>^ \ v -> tyText "TyVarTy" <+> v)-               <+ litTyT (arr $ \ l -> tyText "LitTy" <+> ppSDoc l)-               <+ appTyT ppType ppType (\ ty1 ty2 -> tyText "AppTy" $$ nest 2 (cat [parens ty1, parens ty2]))-               <+ funTyT ppType ppType (\ ty1 ty2 -> tyText "FunTy" $$ nest 2 (cat [parens ty1, parens ty2]))-               <+ forAllTyT ppVar ppType (\ v ty -> tyText "ForAllTy" <+> v $$ nest 2 (parens ty))-               <+ tyConAppT (arr ppSDoc) (const ppType) (\ con tys -> tyText "TyConApp" <+> con $$ nest 2 (vlist $ map parens tys))--        ppCoercion :: PrettyH Coercion-        ppCoercion =  reflT (ppType >>^ \ ty -> coText "Refl" $$ nest 2 (parens ty))-                   <+ coVarCoT (ppVar >>^ \ v -> coText "CoVarCo" <+> v)-                   <+ symCoT (ppCoercion >>^ \ co -> coText "SymCo" $$ nest 2 (parens co))-                   <+ appCoT ppCoercion ppCoercion (\ co1 co2 -> coText "AppCo" $$ nest 2 (cat [parens co1, parens co2]))-                   <+ forAllCoT ppVar ppCoercion (\ v co -> coText "ForAllCo" <+> v $$ nest 2 (parens co))-                   <+ transCoT ppCoercion ppCoercion (\ co1 co2 -> coText "TransCo" $$ nest 2 (cat [parens co1, parens co2]))-                   <+ tyConAppCoT (arr $ ppSDoc) (const ppCoercion) (\ con coes -> coText "TyConAppCo" <+> con $$ nest 2 (vlist $ map parens coes))-                   <+ unsafeCoT ppType ppType (\ ty1 ty2 -> coText "UnsafeCo" $$ nest 2 (cat [parens ty1, parens ty2]))-                   <+ nthCoT (arr $ coText . show) ppCoercion (\ n co -> coText "NthCo" <+> n $$ parens co)-                   <+ instCoT ppCoercion ppType (\ co ty -> coText "InstCo" $$ nest 2 (cat [parens co, parens ty]))-#if __GLASGOW_HASKELL__ > 706-        -- TODO: Figure out how to properly pp new branched Axioms and Left/Right Coercions-                   <+ axiomInstCoT (arr ppSDoc) (arr ppSDoc) (const ppCoercion) (\ ax idx coes -> coText "AxiomInstCo" <+> ax <+> idx $$ nest 2 (vlist $ map parens coes))-                   <+ lrCoT (arr ppSDoc) ppCoercion (\ lr co -> coText "LRCo" <+> lr $$ nest 2 (parens co))-#else-                   <+ axiomInstCoT (arr ppSDoc) (const ppCoercion) (\ ax coes -> coText "AxiomInstCo" <+> ax $$ nest 2 (vlist $ map parens coes))-#endif--        ppVar :: PrettyH Var-        ppVar = arr $ \ v -> let modCol | GHC.isTyVar v = typeColor-                                        | GHC.isCoVar v = coercionColor-                                        | otherwise     = idColor-                              in modCol (ppSDoc v)--    promoteT (ppCoreExpr :: PrettyH GHC.CoreExpr)-     <+ promoteT (ppCoreProg :: PrettyH CoreProg)-     <+ promoteT (ppCoreBind :: PrettyH GHC.CoreBind)-     <+ promoteT (ppCoreDef  :: PrettyH CoreDef)-     <+ promoteT (ppModGuts  :: PrettyH GHC.ModGuts)-     <+ promoteT (ppCoreAlt  :: PrettyH GHC.CoreAlt)-     <+ promoteT (ppType     :: PrettyH GHC.Type)-     <+ promoteT (ppCoercion :: PrettyH Coercion)-----------------------------------------------------------------------------
− src/Language/HERMIT/PrettyPrinter/Clean.hs
@@ -1,422 +0,0 @@-{-# LANGUAGE CPP, LambdaCase, MultiWayIf #-}--module Language.HERMIT.PrettyPrinter.Clean-  ( -- * HERMIT's Clean Pretty-Printer for GHC Core-    corePrettyH-  )-where--import Control.Arrow hiding ((<+>))-import Control.Applicative ((<$>))--import Data.List (intersperse)-import Data.Char (isSpace)-import Data.Set (notMember)--import GhcPlugins (TyCon(..), Coercion(..), Var(..), Expr(..))-import qualified GhcPlugins as GHC--import Language.HERMIT.Context-import Language.HERMIT.Core-import Language.HERMIT.GHC-import Language.HERMIT.Kure-import Language.HERMIT.Monad-import Language.HERMIT.Syntax--import Language.HERMIT.PrettyPrinter.Common--import Language.HERMIT.Primitive.Common--import Pair--import Text.PrettyPrint.MarkedHughesPJ as PP----------------------------------------------------------------------------------------------------data RetExpr-        = RetLam PathH [DocH] PathH DocH-        | RetLet PathH [DocH] PathH DocH-        | RetApp DocH [RetExpr]-        | RetForAll PathH [DocH] PathH DocH-        | RetArrowType [DocH] -- TODO: store PathH here to mark arrows-        | RetExpr DocH-        | RetAtom DocH         -- parens not needed-        | RetEmpty--retApp :: RetExpr -> RetExpr -> RetExpr-retApp f             RetEmpty = f-retApp RetEmpty      e        = e-retApp (RetApp f es) e        = RetApp f (es ++ [e])-retApp f             e        = RetApp (parenExpr f) [e]--retApps :: RetExpr -> [RetExpr] -> RetExpr-retApps = foldl retApp--retLam :: PathH -> RetExpr -> RetExpr -> RetExpr-retLam _ RetEmpty e            = e-retLam p v (RetLam _ vs pb e)  = RetLam p (parenExpr v : vs) pb e-retLam p v e                   = RetLam p [parenExpr v] (p ++ [Lam_Body]) (normalExpr e)--retLet :: PathH -> RetExpr -> RetExpr -> RetExpr-retLet _ RetEmpty body                    = body-retLet p bnd      (RetLet _ bnds pb body) = RetLet p (normalExpr bnd : bnds) pb body-retLet p bnd      body                    = RetLet p [normalExpr bnd] (p ++ [Let_Body]) (normalExpr body)--retForAll :: PathH -> Crumb -> RetExpr -> RetExpr -> RetExpr-retForAll _ _ RetEmpty ty                      = ty-retForAll p _  v       (RetForAll _ vs pb ty)  = RetForAll p (parenExpr v : vs) pb ty-retForAll p cr v       ty                      = RetForAll p [parenExpr v] (p ++ [cr]) (normalExpr ty)--retArrowType :: RetExpr -> RetExpr -> RetExpr-retArrowType ty1 (RetArrowType tys) = RetArrowType (parenExprExceptApp ty1 : tys)-retArrowType ty1 ty2                = RetArrowType [parenExprExceptApp ty1, parenExprExceptApp ty2]----------------------------------------------------------------------------------------------------isEmptyR :: RetExpr -> Bool-isEmptyR RetEmpty = True-isEmptyR _        = False--isAtom :: RetExpr -> Bool-isAtom (RetAtom _) = True-isAtom _           = False----------------------------------------------------------------------------------------------------normalExpr :: RetExpr -> DocH-normalExpr  RetEmpty           = empty-normalExpr (RetAtom e)         = e-normalExpr (RetExpr e)         = e-normalExpr (RetLam p vs pb e)  = hang (attrP p (specialSymbol LambdaSymbol) <+> hsep vs <+> attrP pb (specialSymbol RightArrowSymbol)) 2 e-normalExpr (RetLet p vs pb e)  = sep [ attrP p (keyword "let") <+> vcat vs, attrP pb (keyword "in") <+> e ]-normalExpr (RetApp f es)       = let (atoms,exprs) = span isAtom es-                                  in sep [ hsep (f : map normalExpr atoms)-                                         , nest 2 (sep $ map parenExpr exprs) ]-normalExpr (RetForAll p vs pb ty) = attrP p (specialSymbol ForallSymbol) <+> hsep vs <+> attrP pb (symbol '.') <+> ty-normalExpr (RetArrowType tys)     = hsep (intersperse typeArrow tys)--parenExpr :: RetExpr -> DocH-parenExpr RetEmpty      = empty-parenExpr (RetAtom e)   = e-parenExpr (RetApp d []) = d-parenExpr other         = ppParens (normalExpr other)--parenExprExceptApp :: RetExpr -> DocH-parenExprExceptApp e@(RetApp _ _) = normalExpr e-parenExprExceptApp e              = parenExpr e----------------------------------------------------------------------------------------------------attrPAtomExpr :: PathH -> RetExpr -> RetExpr-attrPAtomExpr p (RetAtom d) = RetAtom (attrP p d)-attrPAtomExpr p (RetExpr d) = RetExpr (attrP p d)-attrPAtomExpr _ e           = e----------------------------------------------------------------------------------------------------ppParens :: DocH -> DocH-ppParens p = symbol '(' <> p <> symbol ')'----------------------------------------------------------------------------------------------------specialSymbol :: SpecialSymbol -> DocH-specialSymbol = markColor SyntaxColor . specialFont . char . renderSpecial--symbol :: Char -> DocH-symbol = markColor SyntaxColor . char--keyword :: String -> DocH-keyword = markColor KeywordColor . text---coChar :: Char -> DocH-coChar = coercionColor . char--coSymbol :: SpecialSymbol -> DocH-coSymbol = coercionColor . specialFont . char . renderSpecial--castSymbol :: DocH-castSymbol = coSymbol CastSymbol--coercionSymbol :: DocH-coercionSymbol = coSymbol CoercionSymbol--coercionBindSymbol :: DocH-coercionBindSymbol = coSymbol CoercionBindSymbol--coKeyword :: String -> DocH-coKeyword = coText -- An alternative would be keyword.---tySymbol :: SpecialSymbol -> DocH-tySymbol = typeColor . specialFont . char . renderSpecial--typeSymbol :: DocH-typeSymbol = tySymbol TypeSymbol--typeBindSymbol :: DocH-typeBindSymbol = tySymbol TypeBindSymbol--typeArrow :: DocH-typeArrow = tySymbol RightArrowSymbol----------------------------------------------------------------------------------------------------hasType :: DocH -> DocH -> DocH-e `hasType` ty = e <+> tySymbol TypeOfSymbol <+> ty------------------------------------------------------------------------------------------------------ TODO: PrettyOptions should be in the context.---- | Pretty print a fragment of GHC Core using HERMIT's \"Clean\" pretty printer.-corePrettyH :: PrettyOptions -> PrettyH CoreTC-corePrettyH opts =-    let-        -- Use for any GHC structure-        ppSDoc :: GHC.Outputable a => PrettyH a-        ppSDoc = do dynFlags <- constT GHC.getDynFlags-                    arr (toDoc . GHC.showSDoc dynFlags . GHC.ppr)-            where toDoc s | any isSpace s = parens (text s)-                          | otherwise     = text s--        ppVar :: Translate PrettyC HermitM Var RetExpr-        ppVar = readerT $ \ v -> GHC.varName ^>> ppName (varColor v)--        varColor :: Var -> SyntaxForColor-        varColor var | GHC.isTyVar var = TypeColor-                     | GHC.isCoVar var = CoercionColor-                     | otherwise       = IdColor--        ppName :: SyntaxForColor -> Translate PrettyC HermitM GHC.Name RetExpr-        ppName color = (GHC.nameOccName >>> GHC.occNameString) ^>> arr (\ name -> let doc  = markColor color (text name)-                                                                                           -- TODO: is "isScriptInfixId" the right predicate to use here?-                                                                                   in RetAtom $ if all isScriptInfixIdChar name-                                                                                                 then ppParens doc-                                                                                                 else doc-                                                                       )--        ppLitTy :: Translate PrettyC HermitM TyLit RetExpr-        ppLitTy = arr $ \case-                          NumTyLit i  -> RetAtom $ tyText (show i)-                          StrTyLit fs -> RetAtom $ tyText (show fs)--        ppTyCon :: Translate PrettyC HermitM TyCon RetExpr-        ppTyCon = GHC.getName ^>> ppName TypeColor--        ppTyConCo :: Translate PrettyC HermitM TyCon RetExpr-        ppTyConCo = GHC.getName ^>> ppName CoercionColor--        -- binders are vars that is bound by lambda or case, etc.-        -- depending on the mode, they might not be displayed-        ppBinderMode :: Translate PrettyC HermitM Var RetExpr-        ppBinderMode = do v <- idR-                          if-                             | GHC.isTyVar v -> case po_exprTypes opts of-                                                                   Omit     -> return (RetEmpty)-                                                                   Abstract -> return (RetAtom typeBindSymbol)-                                                                   _        -> ppVar-                             | GHC.isCoVar v -> case po_coercions opts of-                                                                   Omit     -> return (RetEmpty)-                                                                   Abstract -> return (RetAtom coercionBindSymbol)-                                                                   Show     -> ppVar-                                                                   Kind     -> do pCoKind <- ppCoKind <<^ CoVarCo-                                                                                  return (RetExpr (coercionBindSymbol `hasType` pCoKind))-                                                                  -- TODO: refactor this to be more systematic.  It should be possible to request type sigs for all type bindings.-                             | otherwise       -> ppVar--        ppModGuts :: PrettyH GHC.ModGuts-        ppModGuts = do name <- ppSDoc <<^ GHC.mg_module-                       vtys <- mapT (ppVar &&& (ppType <<^ GHC.idType)) <<< modGutsT progIdsT (\ _ ids -> ids)-                       let defs = [ normalExpr v `hasType` ty | (v,ty) <- vtys ]-                       return $ hang (keyword "module" <+> name <+> keyword "where") 2 (vcat defs)--        -- DocH is not a monoid.-        ppCoreProg :: PrettyH CoreProg-        ppCoreProg = progConsT ppCoreBind ppCoreProg ($+$) <+ progNilT empty--        ppCoreBind :: PrettyH GHC.CoreBind-        ppCoreBind =   (nonRecT idR (ppCoreExprR &&& ppTypeSig) (,) >>> ppDef)-                    <+ (do p <- rootPathT-                           recT (const ppCoreDef) (\ bnds -> attrP p (keyword "rec") <+> vcat bnds)-                       )---        ppCoreAlt :: PrettyH GHC.CoreAlt-        ppCoreAlt = do p <- rootPathT-                       altT (readerT $ \case-                                          GHC.DataAlt dcon -> return (GHC.dataConName dcon) >>> ppName IdColor >>^ parenExpr-                                          GHC.LitAlt lit   -> return lit >>> ppSDoc-                                          GHC.DEFAULT      -> return (symbol '_')-                            )-                            (\ _ -> ppBinderMode)-                            ppCoreExpr-                            (\ con vs e -> hang (con <+> hsep (map parenExpr vs) <+> attrP p (specialSymbol RightArrowSymbol)) 2 e)--        ppCoreDef :: PrettyH CoreDef-        ppCoreDef = defT idR (ppCoreExprR &&& ppTypeSig) (,) >>> ppDef--        ppDef :: PrettyH (Var,(RetExpr,DocH))-        ppDef = do p          <- rootPathT-                   (v,(e,ty)) <- idR-                   case po_coercions opts of-                     Omit | GHC.isCoVar v  -> return empty-                     Kind | GHC.isCoVar v  -> return $ case po_exprTypes opts of-                                                         Show -> (coercionBindSymbol `hasType` ty) $+$ (coercionBindSymbol <+> symbol '=' <+> coercionSymbol)-                                                         _    -> coercionBindSymbol <+> attrP p (symbol '=') <+> normalExpr e-                     _                     -> do pv  <- normalExpr ^<< ppBinderMode <<< return v-                                                 let pre  = pv <+> symbol '='-                                                     body = case e of -- This is an ugly hack-                                                              RetLam p' vs pb e0 -> hang (pre <+> attrP p' (specialSymbol LambdaSymbol) <+> hsep vs <+> attrP pb (specialSymbol RightArrowSymbol)) 2 e0-                                                              _                 -> hang pre 2 (normalExpr e)-                                                 return $ case po_exprTypes opts of-                                                            Omit | GHC.isTyVar v -> empty-                                                            Show                 -> (pv `hasType` ty) $+$ body-                                                            _                    -> body---        ppCoreExpr :: PrettyH GHC.CoreExpr-        ppCoreExpr = ppCoreExprR >>^ normalExpr--        ppCoreExprR :: Translate PrettyC HermitM GHC.CoreExpr RetExpr-        ppCoreExprR = rootPathT >>= ppCoreExprPR-          where-            ppCoreExprPR :: PathH -> Translate PrettyC HermitM GHC.CoreExpr RetExpr-            ppCoreExprPR p =-                      lamT ppBinderMode ppCoreExprR (retLam p)--                   <+ letT (RetExpr <$> ppCoreBind) ppCoreExprR (retLet p)-                   -- HACKs-    {--                   <+ (acceptR (\ e -> case e of-                                         GHC.App (Var v) (GHC.Type t) | po_exprTypes opts == Abstract -> True-                                         _ -> False) >>>-                               (appT ppCoreExprR ppCoreExprR (\ (RetAtom e1) (RetAtom e2) ->-                                        RetAtom (e1 <+> e2))))-    -}-                   <+ (acceptR (\ e -> case e of-                                         App (Type _) (Lam {}) | po_exprTypes opts == Omit -> True-                                         App (App (Var _) (Type _)) (Lam {}) | po_exprTypes opts == Omit -> True-                                         _ -> False) >>>-                               (appT ppCoreExprR ppCoreExprR (\ (RetAtom e1) (RetLam p' vs pb e0) ->-                                        RetExpr $ hang (e1 <+>-                                                            symbol '(' <>-                                                            attrP p' (specialSymbol LambdaSymbol) <+>-                                                            hsep vs <+>-                                                            attrP pb (specialSymbol RightArrowSymbol)) 2 (e0 <> symbol ')')))-                      )--                   <+ appT ppCoreExprR ppCoreExprR retApp-                   <+ caseT ppCoreExpr ppVar ppTypeModeR (const ppCoreAlt) (\ s w ty alts -> RetExpr $ attrP p ((keyword "case" <+> s <+> keyword "of" <+> parenExpr w <+> parenExpr ty) $$ nest 2 (vcat alts)))--                   <+ varT (attrPAtomExpr p <$> (do (c,i) <- exposeT-                                                    if (GHC.isLocalId i) && (i `notMember` boundVars c)-                                                      then GHC.varName ^>> ppName WarningColor-                                                      else ppVar-                                                )-                           )--                   <+ litT ((RetAtom . attrP p) <$> ppSDoc)-                   <+ typeT (attrPAtomExpr p <$> ppTypeModeR)-                   <+ coercionT (attrPAtomExpr p <$> ppCoercionModeR)-                   <+ castT ppCoreExprR ppCoercionModeR (\ e co -> if isEmptyR co-                                                                    then e-                                                                    else RetExpr (parenExprExceptApp e <+> attrP p castSymbol <+> parenExprExceptApp co)-                                                        )-                   <+ tickT ppSDoc ppCoreExprR (\ tk e -> RetExpr $ attrP p (text "Tick" $$ nest 2 (tk <+> parenExpr e)))--        ----------------------------------------------------------------------        ppType :: PrettyH Type-        ppType = ppTypeR >>^ normalExpr--        ppTypeModeR :: Translate PrettyC HermitM Type RetExpr-        ppTypeModeR = case po_exprTypes opts of-                        Omit     -> return RetEmpty-                        Abstract -> return (RetAtom typeSymbol)-                        _        -> ppTypeR--        ppTypeR :: Translate PrettyC HermitM Type RetExpr-        ppTypeR = rootPathT >>= ppTypePR-          where-            ppTypePR :: PathH -> Translate PrettyC HermitM Type RetExpr-            ppTypePR p =-                   tyVarT (attrPAtomExpr p <$> ppVar)-                <+ litTyT (attrPAtomExpr p <$> ppLitTy)-                <+ appTyT ppTypeR ppTypeR retApp-                <+ funTyT ppTypeR ppTypeR retArrowType-                <+ forAllTyT ppVar ppTypeR (retForAll p ForAllTy_Body)-                <+ tyConAppT (ppTyCon &&& idR) (const ppTypeR)-                     (\ (pCon,tyCon) tys -> if | GHC.isFunTyCon tyCon && length tys == 2 -> let [ty1,ty2] = tys in retArrowType ty1 ty2-                                               | tyCon == GHC.listTyCon -> RetAtom $ attrP p $ tyText "[" <> (case tys of-                                                                                                                []  -> empty-                                                                                                                t:_ -> normalExpr t)-                                                                                                          <> tyText "]"-                                               | GHC.isTupleTyCon tyCon -> RetAtom $ attrP p $ tyText "(" <> (if null tys-                                                                                                                then empty-                                                                                                                else foldr1 (\ ty r -> ty <> tyText "," <+> r) (map normalExpr tys)-                                                                                                             )-                                                                                                          <> tyText ")"-                                               | otherwise              -> retApps (attrPAtomExpr p pCon) tys-                     )--        ----------------------------------------------------------------------        ppCoercion :: PrettyH Coercion-        ppCoercion = ppCoercionR >>^ normalExpr--        ppCoercionModeR :: Translate PrettyC HermitM Coercion RetExpr-        ppCoercionModeR = case po_coercions opts of-                            Omit     -> return RetEmpty-                            Abstract -> return (RetAtom coercionSymbol)-                            Show     -> ppCoercionR-                            Kind     -> ppCoKind >>^ (\ k -> RetExpr (coercionSymbol `hasType` k))--        ppCoercionR :: Translate PrettyC HermitM Coercion RetExpr-        ppCoercionR = rootPathT >>= ppCoercionPR-          where-            ppCoercionPR :: PathH -> Translate PrettyC HermitM Coercion RetExpr-            ppCoercionPR p =-                           reflT (ppTypeModeR >>^ \ ty -> RetAtom $ attrP p $ if isEmptyR ty then coText "refl" else coText "<" <> normalExpr ty <> coText ">")-                        <+ coVarCoT (attrPAtomExpr p <$> ppVar)-                        <+ symCoT (ppCoercionR >>^ \ co -> RetExpr (attrP p (coKeyword "sym") <+> parenExpr co))-                        <+ forAllCoT ppBinderMode ppCoercionR (retForAll p ForAllCo_Body)-                        <+ transCoT ppCoercionR ppCoercionR (\ co1 co2 -> RetExpr (parenExprExceptApp co1 <+> attrP p (coChar ';') <+> parenExprExceptApp co2))-                        <+ unsafeCoT ppTypeModeR ppTypeModeR (\ ty1 ty2 -> (if isEmptyR ty1 && isEmptyR ty2 then RetAtom else RetExpr)-                                                                           (attrP p (coKeyword "unsafe") <+> parenExpr ty1 <+> parenExpr ty2)-                                                             )-                        <+ nthCoT idR ppCoercionR (\ n co -> RetExpr (attrP p (coKeyword "nth") <+> attrP p (coText $ show n) <+> parenExpr co))-                        <+ instCoT ppCoercionR ppTypeModeR (\ co ty -> if isEmptyR ty-                                                                         then RetExpr (attrP p (coText "inst") <+> parenExpr co)-                                                                         else RetExpr (parenExprExceptApp co <+> attrP p (coChar '@') <+> parenExprExceptApp ty)-                                                           )-                        <+ tyConAppCoT (attrPAtomExpr p <$> ppTyConCo) (const ppCoercionR) retApps-                        <+ appCoT ppCoercionR ppCoercionR retApp-#if __GLASGOW_HASKELL__ > 706-        -- TODO: Figure out how to properly pp new branched Axioms and Left/Right Coercions-                        <+ axiomInstCoT (coAxiomName ^>> ppName CoercionColor) (RetAtom <$> ppSDoc) (const ppCoercionR) (\ ax idx coes -> RetExpr (attrP p (coText "axiomInst") <+> attrP p (parenExpr ax) <+> attrP p (parenExpr idx) <+> sep (map parenExpr coes)))-                        <+ lrCoT (coercionColor <$> ppSDoc) ppCoercionR (\ lr co -> RetExpr (attrP p lr <+> parenExpr co))-#else-                        <+ axiomInstCoT (coAxiomName ^>> ppName CoercionColor) (const ppCoercionR) (\ ax coes -> RetExpr (attrP p (coText "axiomInst") <+> attrP p (parenExpr ax) <+> sep (map parenExpr coes)))-#endif--        ppCoKind :: PrettyH Coercion-        ppCoKind = (GHC.coercionKind >>> unPair) ^>> (ppTypeModeR *** ppTypeModeR) >>^ ( \(ty1,ty2) -> parenExprExceptApp ty1 <+> coText "~#" <+> parenExprExceptApp ty2)--        ----------------------------------------------------------------------        ppTypeSig :: PrettyH GHC.CoreExpr-        ppTypeSig = coercionT ppCoKind <+ (GHC.exprType ^>> ppType)--        ----------------------------------------------------------------------    in  promoteT (ppCoreExpr     :: PrettyH GHC.CoreExpr)-     <+ promoteT (ppCoreProg     :: PrettyH CoreProg)-     <+ promoteT (ppCoreBind     :: PrettyH GHC.CoreBind)-     <+ promoteT (ppCoreDef      :: PrettyH CoreDef)-     <+ promoteT (ppModGuts      :: PrettyH GHC.ModGuts)-     <+ promoteT (ppCoreAlt      :: PrettyH GHC.CoreAlt)-     <+ promoteT (ppType         :: PrettyH GHC.Type)-     <+ promoteT (ppCoercion     :: PrettyH Coercion)--------------------------------------------------------------------------------------------------
− src/Language/HERMIT/PrettyPrinter/Common.hs
@@ -1,481 +0,0 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, TypeFamilies, InstanceSigs,-             MultiParamTypeClasses, RankNTypes, FlexibleContexts #-}--module Language.HERMIT.PrettyPrinter.Common-    ( -- * Documents-      DocH-    , Attr(..)-    , attrP-      -- ** Colors-    , coText-    , tyText-    , coercionColor-    , idColor-    , keywordColor-    , markColor-    , typeColor-    , ShowOption(..)-    , specialFont-    , SpecialSymbol(..)-    , SyntaxForColor(..)-      -- * Renderers-    , coreRenders-    , renderCode-    , RenderCode(..)-    , renderSpecial-    , RenderSpecial-    , Unicode(..)-      -- * Pretty Printer Traversals-    , PrettyH-    , liftPrettyH-    , PrettyC -- intentionally abstract-    , initPrettyC-    , liftPrettyC-    , TranslateDocH(..)-    , TranslateCoreTCDocHBox(..)-      -- * Pretty Printer Options-    , PrettyOptions(..)-    , updateTypeShowOption-    , updateCoShowOption-      -- * Utilities-    , hlist-    , vlist-    ) where--import GhcPlugins hiding (($$), (<>), (<+>))--import Data.Char-import Data.Default-import Data.Monoid hiding ((<>))-import qualified Data.Map as M-import Data.Set (Set)-import qualified Data.Set as S-import Data.Typeable--import Language.HERMIT.Context-import Language.HERMIT.Core-import Language.HERMIT.External-import Language.HERMIT.Kure-import Language.HERMIT.Monad--import System.IO--import Text.PrettyPrint.MarkedHughesPJ as PP---- A HERMIT document-type DocH = MDoc HermitMark---- newtype wrapper for proper instance selection-newtype TranslateDocH a = TranslateDocH { unTranslateDocH :: PrettyH a -> TranslateH a DocH }--data TranslateCoreTCDocHBox = TranslateCoreTCDocHBox (TranslateDocH CoreTC) deriving Typeable--instance Extern (TranslateDocH CoreTC) where-    type Box (TranslateDocH CoreTC) = TranslateCoreTCDocHBox-    box = TranslateCoreTCDocHBox-    unbox (TranslateCoreTCDocHBox i) = i---- These are the zero-width marks on the document-data HermitMark-        = PushAttr Attr-        | PopAttr-    deriving Show---- These are the attributes-data Attr = PathAttr PathH-          | Color SyntaxForColor-          | SpecialFont-    deriving Show--data SyntaxForColor             -- (suggestion)-        = KeywordColor          -- bold-        | SyntaxColor-        | IdColor-        | CoercionColor-        | TypeColor-        | LitColor-        | WarningColor          -- highlight problems like unbound variables-    deriving Show--attr :: Attr -> DocH -> DocH-attr a p = mark (PushAttr a) <> p <> mark PopAttr---- Hack, till we get 'PathAttr' working properly--- The problem is that attributes span over multiple lines,--- messing up the latex output--attrP :: PathH -> DocH -> DocH-attrP _ doc = doc -- attr . PathAttr--tyText :: String -> DocH-tyText = typeColor . PP.text--coText :: String -> DocH-coText = coercionColor . PP.text--idColor :: DocH -> DocH-idColor = markColor IdColor--typeColor :: DocH -> DocH-typeColor = markColor TypeColor--coercionColor :: DocH -> DocH-coercionColor = markColor CoercionColor--keywordColor :: DocH -> DocH-keywordColor = markColor KeywordColor--markColor :: SyntaxForColor -> DocH -> DocH-markColor = attr . Color--specialFont :: DocH -> DocH-specialFont = attr SpecialFont--type PrettyH a = Translate PrettyC HermitM a DocH--- TODO: change monads to something more restricted?---- | Context for PrettyH translations.-data PrettyC = PrettyC { prettyC_path :: AbsolutePath Crumb-                       , prettyC_vars :: Set Var}-                       -- TODO: Add PrettyOptions to PrettyC----------------------------------------------------------------------------instance ReadPath PrettyC Crumb where-  absPath :: PrettyC -> AbsolutePath Crumb-  absPath = prettyC_path-  {-# INLINE absPath #-}--instance ExtendPath PrettyC Crumb where-  (@@) :: PrettyC -> Crumb -> PrettyC-  c @@ n = c { prettyC_path = prettyC_path c @@ n }-  {-# INLINE (@@) #-}--instance AddBindings PrettyC where-  addHermitBindings :: [(Var,HermitBindingSite)] -> PrettyC -> PrettyC-  addHermitBindings vbs c = c { prettyC_vars = foldr S.insert (prettyC_vars c) (map fst vbs) }-                            -- let vhbs = [ (v, (0,b)) | (v,b) <- vbs ] -- TODO: do we care about depth?-                            --  in c { prettyC_bindings = M.fromList vhbs `M.union` prettyC_bindings c }-  {-# INLINE addHermitBindings #-}---- instance ReadBindings PrettyC where---   hermitDepth :: PrettyC -> BindingDepth---   hermitDepth = prettyC_depth----   hermitBindings :: PrettyC -> M.Map Var HermitBinding---   hermitBindings = prettyC_bindings---   {-# INLINE hermitBindings #-}--instance BoundVars PrettyC where-  boundVars :: PrettyC -> Set Var-  boundVars = prettyC_vars----------------------------------------------------------------------------liftPrettyH :: (ReadBindings c, ReadPath c Crumb) => PrettyH a -> Translate c HermitM a DocH-liftPrettyH pp = translate $ \ c -> apply pp (liftPrettyC c)--liftPrettyC :: (ReadBindings c, ReadPath c Crumb) => c -> PrettyC-liftPrettyC c = PrettyC { prettyC_path  = absPath c-                        , prettyC_vars  = boundVars c }--initPrettyC :: PrettyC-initPrettyC = PrettyC { prettyC_path = mempty-                      , prettyC_vars = S.empty-                      }---- These are *recommendations* to the pretty printer.--data PrettyOptions = PrettyOptions-        { po_fullyQualified  :: Bool            -- ^ Do you show fully qualified names?-        , po_exprTypes       :: ShowOption      -- ^ Do you hide types, and type arguments, as <>?-        , po_coercions       :: ShowOption      -- ^ Do you hide coercions?-        , po_typesForBinders :: ShowOption      -- ^ Do you give the types for all bindings?-        , po_highlight       :: Maybe PathH     -- ^ This region should be highlighted (for sub-expression)-        , po_depth           :: Maybe Int       -- ^ below this depth are ..., Nothing => infinite-        , po_notes           :: Bool            -- ^ notes might be added to output-        , po_ribbon          :: Float-        , po_width           :: Int-        } deriving Show--data ShowOption = Show | Abstract | Omit | Kind deriving (Eq, Ord, Show, Read)---- Types don't have a Kind showing option.-updateTypeShowOption :: ShowOption -> PrettyOptions -> PrettyOptions-updateTypeShowOption Kind po = po-updateTypeShowOption opt  po = po { po_exprTypes = opt }--updateCoShowOption :: ShowOption -> PrettyOptions -> PrettyOptions-updateCoShowOption opt po  = po { po_coercions = opt }--instance Default PrettyOptions where-  def = PrettyOptions-        { po_fullyQualified  = False-        , po_exprTypes       = Abstract-        , po_coercions       = Abstract-        , po_typesForBinders = Omit-        , po_highlight       = Nothing-        , po_depth           = Nothing-        , po_notes           = False-        , po_ribbon          = 1.2-        , po_width           = 80-        }----------------------------------------------------------------------- The characters for special symbols, which have a special alphabet--data SpecialSymbol-        = LambdaSymbol-        | TypeOfSymbol-        | RightArrowSymbol-        | CastSymbol-        | CoercionSymbol-        | CoercionBindSymbol-        | TypeSymbol-        | TypeBindSymbol-        | ForallSymbol-        deriving (Show, Eq, Ord, Bounded, Enum)--class RenderSpecial a where-        renderSpecial :: SpecialSymbol -> a----- This instance is special.  It is used as an index, forming an association list.--- Thus all of the rhs must be distinct characters.--- Think of RenderSpecial as a special font.-instance RenderSpecial Char where-        renderSpecial LambdaSymbol        = '\\'  -- lambda-        renderSpecial TypeOfSymbol        = ':'   -- ::-        renderSpecial RightArrowSymbol    = '>'   -- ->-        renderSpecial CastSymbol          = '#'   -- "|>"-        renderSpecial CoercionSymbol      = 'C'   -- <<coercion>>>-        renderSpecial CoercionBindSymbol  = 'c'   -- <<coercion>>>-        renderSpecial TypeSymbol          = 'T'   -- <<type>>>-        renderSpecial TypeBindSymbol      = 't'   -- <<type binding>>-        renderSpecial ForallSymbol        = 'F'   -- forall--newtype ASCII = ASCII String--instance Monoid ASCII where-        mempty = ASCII ""-        mappend (ASCII xs) (ASCII ys) = ASCII (xs ++ ys)--instance RenderSpecial ASCII where-        renderSpecial LambdaSymbol        = ASCII "\\"   -- lambda-        renderSpecial TypeOfSymbol        = ASCII "::"   -- ::-        renderSpecial RightArrowSymbol    = ASCII "->"   -- ->-        renderSpecial CastSymbol          = ASCII "|>"   -- "|>"-        renderSpecial CoercionSymbol      = ASCII "~#"   -- <<coercion>>>-        renderSpecial CoercionBindSymbol  = ASCII "~#"   -- <<coercion binding>>>-        renderSpecial TypeSymbol          = ASCII "*"    -- <<type>>>-        renderSpecial TypeBindSymbol      = ASCII "*"    -- <<type binding>>>-        renderSpecial ForallSymbol        = ASCII "\\/"--newtype Unicode = Unicode Char--instance RenderSpecial Unicode where-        renderSpecial LambdaSymbol        = Unicode '\x03BB'-        renderSpecial TypeOfSymbol        = Unicode '\x2237'     -- called PROPORTION-        renderSpecial RightArrowSymbol    = Unicode '\x2192'-        renderSpecial CastSymbol          = Unicode '\x25B9'-        renderSpecial CoercionSymbol      = Unicode '\x25A0'-        renderSpecial CoercionBindSymbol  = Unicode '\x25A1'-        renderSpecial TypeSymbol          = Unicode '\x25b2'-        renderSpecial TypeBindSymbol      = Unicode '\x25b3'-        renderSpecial ForallSymbol        = Unicode '\x2200'--newtype LaTeX = LaTeX String--instance Monoid LaTeX where-        mempty = LaTeX ""-        mappend (LaTeX xs) (LaTeX ys) = LaTeX (xs ++ ys)--instance RenderSpecial LaTeX where-        renderSpecial LambdaSymbol        = LaTeX "\\ensuremath{\\lambda}"-        renderSpecial TypeOfSymbol        = LaTeX ":\\!:"  -- too wide-        renderSpecial RightArrowSymbol    = LaTeX "\\ensuremath{\\shortrightarrow}"-        renderSpecial CastSymbol          = LaTeX "\\ensuremath{\\triangleright}"-        renderSpecial CoercionSymbol      = LaTeX "\\ensuremath{\\blacksquare}"-        renderSpecial CoercionBindSymbol  = LaTeX "\\ensuremath{\\square}"-        renderSpecial TypeSymbol          = LaTeX "\\ensuremath{\\blacktriangle}"-        renderSpecial TypeBindSymbol      = LaTeX "\\ensuremath{\\vartriangle}"-        renderSpecial ForallSymbol        = LaTeX "\\ensuremath{\\forall}"---newtype HTML = HTML String--instance Monoid HTML where-        mempty = HTML ""-        mappend (HTML xs) (HTML ys) = HTML (xs ++ ys)--instance RenderSpecial HTML where-        renderSpecial LambdaSymbol        = HTML "&#955;"-        renderSpecial TypeOfSymbol        = HTML "&#8759;"-        renderSpecial RightArrowSymbol    = HTML "&#8594;"-        renderSpecial CastSymbol          = HTML "&#9657;"-        renderSpecial CoercionSymbol      = HTML "&#9632;"-        renderSpecial CoercionBindSymbol  = HTML "&#9633;"-        renderSpecial TypeSymbol          = HTML "&#9650;"-        renderSpecial TypeBindSymbol      = HTML "&#9651;"-        renderSpecial ForallSymbol        = HTML "&#8704;"---renderSpecialFont :: RenderSpecial a => Char -> Maybe a-renderSpecialFont = fmap renderSpecial . flip M.lookup specialFontMap--specialFontMap :: M.Map Char SpecialSymbol-specialFontMap = M.fromList-                [ (renderSpecial s,s)-                | s <- [minBound..maxBound]-                ]---class (RenderSpecial a, Monoid a) => RenderCode a where-    rStart :: a-    rStart = mempty-    rEnd :: a-    rEnd = mempty--    rDoHighlight :: Bool -> [Attr]           -> a-    rPutStr      :: String -> a--renderCode :: RenderCode a => PrettyOptions -> DocH -> a-renderCode opts doc = rStart `mappend` PP.fullRender PP.PageMode w rib marker (\ _ -> rEnd) doc []-  where-          -- options-          w = po_width opts-          rib = po_ribbon opts--          marker :: RenderCode a => PP.TextDetails HermitMark -> ([Attr] -> a) -> ([Attr]-> a)-          marker m rest cols@(SpecialFont:_) = case m of-                  PP.Chr ch   -> special [ch] `mappend` rest cols-                  PP.Str str  -> special str `mappend` rest cols-                  PP.PStr str -> special str `mappend` rest cols-                  PP.Mark (PopAttr)    ->-                        let (_:cols') = cols in rDoHighlight False cols' `mappend` rest cols'-                  PP.Mark (PushAttr _) -> error "renderCode: can not have marks inside special symbols"-          marker m rest cols = case m of-                  PP.Chr ch   -> rPutStr [ch] `mappend` rest cols-                  PP.Str str  -> rPutStr str `mappend` rest cols-                  PP.PStr str -> rPutStr str `mappend` rest cols-                  PP.Mark (PushAttr a) ->-                        let cols' = a : cols in rDoHighlight True cols' `mappend` rest cols'-                  PP.Mark (PopAttr) -> do-                        let (_:cols') = cols in rDoHighlight False cols' `mappend` rest cols'--          special txt = mconcat [ code | Just code <- map renderSpecialFont txt ]----- Other options for pretty printing:--- * Does a top level program should function names, or complete listings?----- Moving the renders back into the core hermit-----------------------------------------------------------------------------------coreRenders :: [(String,Handle -> PrettyOptions -> DocH -> IO ())]-coreRenders =-        [ ("latex", \ h w doc -> do-                        let pretty = latexToString $ renderCode w doc-                        hPutStr h pretty)-        , ("html", \ h w doc -> do-                        let HTML pretty = renderCode w doc-                        hPutStr h pretty)-        , ("ascii", \ h w doc -> do-                        let (ASCII pretty) = renderCode w doc-                        hPutStrLn h pretty)-        , ("debug", \ h w doc -> do-                        let (DebugPretty pretty) = renderCode w doc-                        hPutStrLn h pretty)-        ]---- latexVerbatim :: String -> LaTeX -> LaTeX--- latexVerbatim str (LaTeX v) = LaTeX (str ++ v)--latexToString :: LaTeX -> String-latexToString (LaTeX orig) = unlines $ map trunkSpaces $ lines orig where-  trunkSpaces txt = case span isSpace txt of-                       ([],rest) -> rest-                       (pre,rest) -> "\\hspace{" ++ show (length pre) ++ "\\hermitspace}" ++ rest--instance RenderCode LaTeX where-        rPutStr txt  = LaTeX txt--        rDoHighlight False _ = LaTeX "}"-        rDoHighlight _ [] = LaTeX $ "{"-        rDoHighlight _ (Color col:_) = LaTeX $ "{" ++ case col of-                        KeywordColor  -> "\\color{hermit:keyword}"       -- blue-                        SyntaxColor   -> "\\color{hermit:syntax}"        -- red-                        IdColor       -> ""-                        CoercionColor -> "\\color{hermit:coercion}"      -- yellow-                        TypeColor     -> "\\color{hermit:type}"          -- green-                        LitColor      -> "\\color{hermit:lit}"           -- cyan-                        WarningColor  -> "\\color{hermit:warning}"       -- black on yellow-        rDoHighlight o (_:rest) = rDoHighlight o rest--        rEnd = LaTeX "\n" -- \\end{Verbatim}"--{- | Use css to do the colors- -- - > <style type="text/css">- - >  .hermit-syntax {- - >      color: red;- - >  </style>- -}--instance RenderCode HTML where-        rPutStr txt  = HTML txt--        rDoHighlight False _ = HTML "</span>"-        rDoHighlight _ [] = HTML $ "<span>"-        rDoHighlight _ (Color col:_) = HTML $ case col of-                        KeywordColor  -> "<span class=\"hermit-keyword\">"       -- blue-                        SyntaxColor   -> "<span class=\"hermit-syntax\">"        -- red-                        IdColor       -> "<span>"-                        CoercionColor -> "<span class=\"hermit-coercion\">"      -- yellow-                        TypeColor     -> "<span class=\"hermit-type\">"          -- green-                        LitColor      -> "<span class=\"hermit-lit\">"           -- cyan-                        WarningColor  -> "<span class=\"hermit-warning\">"       -- black on yellow-        rDoHighlight o (_:rest) = rDoHighlight o rest-        rEnd = HTML "\n"---instance RenderCode ASCII where-        rPutStr txt  = ASCII txt--        rDoHighlight _ _ = ASCII ""--        rEnd = ASCII "\n"--data DebugPretty = DebugPretty String--instance RenderSpecial DebugPretty where-        renderSpecial sym = DebugPretty ("{" ++ show sym ++ "}")--instance Monoid DebugPretty where-        mempty = DebugPretty ""-        mappend (DebugPretty xs) (DebugPretty ys) = DebugPretty $ xs ++ ys--instance RenderCode DebugPretty where-        rStart = DebugPretty "(START)\n"--        rPutStr txt  = DebugPretty txt--        rDoHighlight True  stk = DebugPretty $ show (True,stk)-        rDoHighlight False stk = DebugPretty $ show (False,stk)--        rEnd = DebugPretty "(END)\n"-----------------------------------------------------------------------------------listify :: (MDoc a -> MDoc a -> MDoc a) -> [MDoc a] -> MDoc a-listify _  []     = PP.text "[]"-listify op (d:ds) = op (PP.text "[ " <> d) (foldr (\e es -> op (PP.text ", " <> e) es) (PP.text "]") ds)---- | like vcat and hcat, only make the list syntax explicit-vlist, hlist :: [MDoc a] -> MDoc a-vlist = listify ($$)-hlist = listify (<+>)---------------------------------------------------------------------------------
− src/Language/HERMIT/PrettyPrinter/GHC.hs
@@ -1,68 +0,0 @@--- | Output the raw Expr constructors. Helpful for writing pattern matching rewrites.-module Language.HERMIT.PrettyPrinter.GHC-  ( -- * GHC's standard Pretty-Printer for GHC Core-    corePrettyH-  )-where--import Control.Arrow hiding ((<+>))--import Data.Char (isSpace)--import qualified GhcPlugins as GHC-import Language.HERMIT.Kure-import Language.HERMIT.Core-import Language.HERMIT.PrettyPrinter.Common--import Text.PrettyPrint.MarkedHughesPJ as PP--------------------------------------------------------------------------------- | This pretty printer is just a reflection of GHC's standard pretty printer.-corePrettyH :: PrettyOptions -> PrettyH CoreTC-corePrettyH opts = do-    dynFlags <- constT GHC.getDynFlags--    let hideNotes = po_notes opts--        -- Use for any GHC structure, the 'showSDoc' prefix is to remind us-        -- that we are eliding infomation here.-        ppSDoc :: (GHC.Outputable a) => a -> MDoc b-        ppSDoc = toDoc . (if hideNotes then id else ("showSDoc: " ++)) . GHC.showSDoc dynFlags . GHC.ppr-            where toDoc s | any isSpace s = parens (text s)-                          | otherwise     = text s--        ppModGuts :: PrettyH GHC.ModGuts-        ppModGuts = arr (ppSDoc . GHC.mg_binds)--        ppCoreProg :: PrettyH CoreProg-        ppCoreProg = arr (ppSDoc . progToBinds)--        ppCoreExpr :: PrettyH GHC.CoreExpr-        ppCoreExpr = arr ppSDoc--        ppCoreBind :: PrettyH GHC.CoreBind-        ppCoreBind = arr ppSDoc--        ppCoreAlt :: PrettyH GHC.CoreAlt-        ppCoreAlt = arr ppSDoc--        ppCoreDef :: PrettyH CoreDef-        ppCoreDef = defT (arr ppSDoc) ppCoreExpr $ \ i e -> i <+> text "=" <+> e--        ppType :: PrettyH GHC.Type-        ppType = arr ppSDoc--        ppCoercion :: PrettyH GHC.Coercion-        ppCoercion = arr ppSDoc--    promoteT (ppCoreExpr :: PrettyH GHC.CoreExpr)-     <+ promoteT (ppCoreProg :: PrettyH CoreProg)-     <+ promoteT (ppCoreBind :: PrettyH GHC.CoreBind)-     <+ promoteT (ppCoreDef  :: PrettyH CoreDef)-     <+ promoteT (ppModGuts  :: PrettyH GHC.ModGuts)-     <+ promoteT (ppCoreAlt  :: PrettyH GHC.CoreAlt)-     <+ promoteT (ppType     :: PrettyH GHC.Type)-     <+ promoteT (ppCoercion :: PrettyH GHC.Coercion)-----------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/AlphaConversion.hs
@@ -1,314 +0,0 @@-{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}-module Language.HERMIT.Primitive.AlphaConversion-       ( -- * Alpha-Renaming and Shadowing-         externals-         -- ** Alpha-Renaming-       , alpha-       , alphaLam-       , alphaCaseBinder-       , alphaAltWith-       , alphaAltVars-       , alphaAlt-       , alphaCase-       , alphaLetWith-       , alphaLetVars-       , alphaLet-       , alphaConsWith-         -- ** Shadow Detection and Unshadowing-       , unshadow-       , visibleVarsT-       , freshNameGenT-       , freshNameGenAvoiding-       , replaceVarR-       )-where--import GhcPlugins hiding (empty)--import Control.Arrow-import Control.Monad (liftM, liftM2)-import Data.Char (isDigit)-import Data.Maybe (fromMaybe, listToMaybe)-import Data.Monoid-import Data.Set (Set, union, unions, member, notMember, toList, fromList)-import qualified Data.Set as S--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.External--import Language.HERMIT.Primitive.GHC hiding (externals)-import Language.HERMIT.Primitive.Common--import qualified Language.Haskell.TH as TH--import Prelude hiding (exp)----------------------------------------------------------------------------- | Externals for alpha-renaming.-externals :: [External]-externals = map (.+ Deep)-         [  external "alpha" (alpha :: RewriteH Core)-               [ "Renames the bound variables at the current node."]-         ,  external "alpha-lam" (promoteExprR . alphaLam . Just :: TH.Name -> RewriteH Core)-               [ "Renames the bound variable in a Lambda expression to the given name."]-         ,  external "alpha-lam" (promoteExprR  (alphaLam Nothing) :: RewriteH Core)-               [ "Renames the bound variable in a Lambda expression."]-         ,  external "alpha-case-binder" (promoteExprR . alphaCaseBinder . Just :: TH.Name -> RewriteH Core)-               [ "Renames the binder in a Case expression to the given name."]-         ,  external "alpha-case-binder" (promoteExprR (alphaCaseBinder Nothing) :: RewriteH Core)-               [ "Renames the binder in a Case expression."]-         ,  external "alpha-alt" (promoteAltR alphaAlt :: RewriteH Core)-               [ "Renames all binders in a Case alternative."]-         ,  external "alpha-alt" (promoteAltR . alphaAltWith :: [TH.Name] -> RewriteH Core)-               [ "Renames all binders in a Case alternative using the user-provided list of new names."]-         ,  external "alpha-case" (promoteExprR alphaCase :: RewriteH Core)-               [ "Renames all binders in a Case alternative."]-         ,  external "alpha-let" (promoteExprR . alphaLetWith :: [TH.Name] -> RewriteH Core)-               [ "Renames the bound variables in a Let expression using a list of suggested names."]-         ,  external "alpha-let" (promoteExprR alphaLet :: RewriteH Core)-               [ "Renames the bound variables in a Let expression."]-         ,  external "alpha-top" (promoteProgR . alphaConsWith :: [TH.Name] -> RewriteH Core)-               [ "Renames the bound identifiers in the top-level binding group at the head of the program using a list of suggested names."]-         -- ,  external "alpha-top" (promoteProgR alphaCons)-         --       [ "Renames the bound identifiers in the top-level binding at the head of the program."]-         -- ,  external "alpha-program" (promoteProgR alphaProg)-         --       [ "Renames identifiers bound at the top-level of the program."]-         ,  external "unshadow" (unshadow :: RewriteH Core)-                [ "Rename local variables with manifestly unique names (x, x0, x1, ...)."]-         ]------------------------------------------------------------------------------- freshNameGen is a function used in conjunction with cloneVarH, which clones an existing 'Var'.--- But, what name should the new Id have?--- cloneVarH generates a new Unique -- so we are positive that the new Var will be new,--- but freshNameGen tries to assign a Name that will be meaningful to the user, and--- not shadow other names in scope.--- So,  we start with the name of the original Id, and add an integer suffix---  x  goes to x0 or x1 or ...--- and we do not want this newly generated name to shadow either:--- 1.  Any free variable name in the active Expr; or--- 2.  Any bound variables in context.---- | List all visible identifiers (in the expression or the context).-visibleVarsT :: (BoundVars c, Monad m) => Translate c m CoreExpr (Set Var)-visibleVarsT = liftM2 union boundVarsT freeVarsT---- | If a name is provided replace the string with that,---   otherwise modify the string making sure to /not/ clash with any visible variables.-freshNameGenT :: (BoundVars c, Monad m) => Maybe TH.Name -> Translate c m CoreExpr (String -> String)-freshNameGenT mn = freshNameGenAvoiding mn `liftM` visibleVarsT---- | Use the optional argument if given, otherwise generate a new name avoiding clashes with the list of variables.-freshNameGenAvoiding :: Maybe TH.Name -> Set Var -> (String -> String)-freshNameGenAvoiding mn vs str = maybe (inventNames vs str) TH.nameBase mn---- | Invent a new String based on the old one, but avoiding clashing with the given list of identifiers.-inventNames :: Set Var -> String -> String-inventNames curr old = head-                     [ nm-                     | nm <- old : [ base ++ show uq | uq <- [start ..] :: [Int] ]-                     , nm `notMember` names-                     ]-   where-           names = S.map getOccString curr-           nums = reverse $ takeWhile isDigit (reverse old)-           baseLeng = length $ drop (length nums) old-           base = take baseLeng old-           start = case reads nums of-                     [(v,_)] -> v + 1-                     _       -> 0----- | Remove all variables from the first set that shadow a variable in the second set.-shadowedBy :: Set Var -> Set Var -> Set Var-shadowedBy vs fvs = S.filter (\ v -> getOccString v `member` S.map getOccString fvs) vs---- | Lifted version of 'shadowedBy'.---   Additionally, it fails if no shadows are found.-shadowedByT :: MonadCatch m => Translate c m a (Set Var) -> Translate c m a (Set Var) -> Translate c m a (Set Var)-shadowedByT t1 t2 = setFailMsg "No shadows detected." $ (liftM2 shadowedBy t1 t2) >>> acceptR (not . S.null)---- | Rename local variables with manifestly unique names (x, x0, x1, ...).---   Does not rename top-level definitions.-unshadow :: forall c. (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core-unshadow = setFailMsg "No shadows to eliminate." $-           anytdR (promoteExprR unshadowExpr <+ promoteAltR unshadowAlt)--  where-    unshadowExpr :: Rewrite c HermitM CoreExpr-    unshadowExpr = do vs <- shadowedByT (liftM2 union boundVarsT freeVarsT) (liftM fromList (letVarsT <+ fmap return (caseWildIdT <+ lamVarT)))-                      alphaLam Nothing <+ alphaLetVars (toList vs) <+ alphaCaseBinder Nothing--    unshadowAlt :: Rewrite c HermitM CoreAlt-    unshadowAlt = shadowedByT (liftM fromList altVarsT) (liftM2 union boundVarsT altFreeVarsT) >>= (alphaAltVars . toList)----------------------------------------------------------------------------- | Replace all occurrences of a specified variable.---   Arguments are the variable to replace and the replacement variable, respectively.-replaceVarR :: (ExtendPath c Crumb, AddBindings c, Injection a Core, MonadCatch m) => Var -> Var -> Rewrite c m a-replaceVarR v v' = extractR $ tryR $ substR v $ varToCoreExpr v'---- | Given a variable to replace, and a replacement, produce a 'Var' @->@ 'Var' function that---   acts as in identity for all 'Var's except the one to replace, for which it returns the replacment.---   Don't export this, it'll likely just cause confusion.-replaceVar :: Var -> Var -> (Var -> Var)-replaceVar v v' = replaceVars [(v,v')]---- | Given a lists of variables to replace, and their replacements, produce a 'Var' @->@ 'Var' function that---   acts as in identity for all 'Var's except the ones to replace, for which it returns the replacment.---   Don't export this, it'll likely just cause confusion.-replaceVars :: [(Var,Var)] -> (Var -> Var)-replaceVars kvs v = fromMaybe v (lookup v kvs)----------------------------------------------------------------------------- | Alpha rename a lambda binder.  Optionally takes a suggested new name.-alphaLam :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Rewrite c HermitM CoreExpr-alphaLam mn = setFailMsg (wrongFormForAlpha "Lam v e") $-              do (v, nameModifier) <- lamT idR (freshNameGenT mn) (,)-                 v' <- constT (cloneVarH nameModifier v)-                 lamAnyR (arr $ replaceVar v v') (replaceVarR v v')----------------------------------------------------------------------------- | Alpha rename a case binder.  Optionally takes a suggested new name.-alphaCaseBinder :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Rewrite c HermitM CoreExpr-alphaCaseBinder mn = setFailMsg (wrongFormForAlpha "Case e v ty alts") $-                     do Case _ v _ _ <- idR-                        nameModifier <- freshNameGenT mn-                        v' <- constT (cloneVarH nameModifier v)-                        caseAnyR idR (return v') idR (\ _ -> replaceVarR v v')----------------------------------------------------------------------------- | Rename the specified variable in a case alternative.  Optionally takes a suggested new name.-alphaAltVar :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Var -> Rewrite c HermitM CoreAlt-alphaAltVar mn v = do nameModifier <- altT idR (\ _ -> idR) (freshNameGenT mn) (\ _ _ nameGen -> nameGen)-                      v' <- constT (cloneVarH nameModifier v)-                      altAnyR (fail "") (\ _ -> arr (replaceVar v v')) (replaceVarR v v')---- | Rename the specified variables in a case alternative, using the suggested names where provided.-alphaAltVarsWith :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [(Maybe TH.Name,Var)] -> Rewrite c HermitM CoreAlt-alphaAltVarsWith = andR . map (uncurry alphaAltVar)---- | Rename the variables bound in a case alternative with the given list of suggested names.-alphaAltWith :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [TH.Name] -> Rewrite c HermitM CoreAlt-alphaAltWith ns = do vs <- altVarsT-                     alphaAltVarsWith $ zip (map Just ns) vs---- | Rename the specified variables in a case alternative.-alphaAltVars :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreAlt-alphaAltVars = alphaAltVarsWith . zip (repeat Nothing)---- | Rename all identifiers bound in a case alternative.-alphaAlt :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreAlt-alphaAlt = altVarsT >>= alphaAltVars----------------------------------------------------------------------------- | Rename all identifiers bound in a case expression.-alphaCase :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr-alphaCase = alphaCaseBinder Nothing >+> caseAllR idR idR idR (const alphaAlt)----------------------------------------------------------------------------- | Alpha rename a non-recursive let binder.  Optionally takes a suggested new name.-alphaLetNonRec :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Rewrite c HermitM CoreExpr-alphaLetNonRec mn = setFailMsg (wrongFormForAlpha "Let (NonRec v e1) e2") $-                    do (v, nameModifier) <- letNonRecT idR mempty (freshNameGenT mn) (\ v () nameMod -> (v, nameMod))-                       v' <- constT (cloneVarH nameModifier v)-                       letNonRecAnyR (return v') idR (replaceVarR v v')---- | Alpha rename a non-recursive let binder if the variable appears in the argument list.  Optionally takes a suggested new name.-alphaLetNonRecVars :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> [Var] -> Rewrite c HermitM CoreExpr-alphaLetNonRecVars mn vs = whenM ((`elem` vs) `liftM` letNonRecVarT) (alphaLetNonRec mn)---- | Rename the specified identifier bound in a recursive let.  Optionally takes a suggested new name.-alphaLetRecId :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Maybe TH.Name -> Id -> Rewrite c HermitM CoreExpr-alphaLetRecId mn v = setFailMsg (wrongFormForAlpha "Let (Rec bs) e") $-                     do usedVars <- liftM2 union boundVarsT-                                                 $ letRecT (\ _ -> defT idR freeVarsT S.insert) freeVarsT (\ bndfvs vs -> unions (vs:bndfvs))-                               --     letVarsT  `mappend`-                              --      letRecDefT (\ _ -> (idR,freeVarsT)) freeVarsT (\ bndfvs vs -> concatMap snd bndfvs ++ vs)-                        v' <- constT (cloneVarH (freshNameGenAvoiding mn usedVars) v)-                        letRecDefAnyR (\ _ -> (arr (replaceVar v v'), replaceVarR v v')) (replaceVarR v v')---- | Rename the specified identifiers in a recursive let, using the suggested names where provided.-alphaLetRecIdsWith :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [(Maybe TH.Name,Id)] -> Rewrite c HermitM CoreExpr-alphaLetRecIdsWith = andR . map (uncurry alphaLetRecId)---- | Rename the identifiers bound in a Let with the given list of suggested names.-alphaLetWith :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [TH.Name] -> Rewrite c HermitM CoreExpr-alphaLetWith ns = alphaLetNonRec (listToMaybe ns)-                  <+ (letRecIdsT >>= (alphaLetRecIdsWith . zip (map Just ns)))---- | Rename the specified variables bound in a let.-alphaLetVars :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => [Var] -> Rewrite c HermitM CoreExpr-alphaLetVars vs = alphaLetNonRecVars Nothing vs <+ alphaLetRecIdsWith (zip (repeat Nothing) vs)---- | Rename all identifiers bound in a Let.-alphaLet :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM CoreExpr-alphaLet = letVarsT >>= alphaLetVars----------------------------------------------------------------------------- | Alpha rename a non-recursive top-level binder.  Optionally takes a suggested new name.-alphaConsNonRec :: (ExtendPath c Crumb, AddBindings c) => TH.Name -> Rewrite c HermitM CoreProg-alphaConsNonRec n = setFailMsg (wrongFormForAlpha "ProgCons (NonRec v e) p") $-                    do ProgCons (NonRec v _) _ <- idR-                       v' <- constT (cloneVarH (\ _ -> TH.nameBase n) v)-                       consNonRecAnyR (return v') idR (replaceVarR v v')---- -- | Alpha rename a non-recursive top-level binder if the identifier appears in the argument list.  Optionally takes a suggested new name.--- alphaConsNonRecIds :: Maybe TH.Name -> [Id] -> Rewrite c m CoreProg--- alphaConsNonRecIds mn vs = whenM ((`elem` vs) <$> consNonRecIdT) (alphaConsNonRec mn)---- | Rename the specified identifier bound in a recursive top-level binder.  Optionally takes a suggested new name.-alphaConsRecId :: (ExtendPath c Crumb, AddBindings c) => TH.Name -> Id -> Rewrite c HermitM CoreProg-alphaConsRecId n v =  setFailMsg (wrongFormForAlpha "ProgCons (Rec bs) p") $-                      do v' <- constT (cloneVarH (\ _ -> TH.nameBase n) v)-                         consRecDefAnyR (\ _ -> (arr (replaceVar v v'), replaceVarR v v')) (replaceVarR v v')---- | Rename the specified identifiers in a recursive top-level binding at the head of a program, using the suggested names where provided.-alphaConsRecIdsWith :: (ExtendPath c Crumb, AddBindings c) => [(TH.Name,Id)] -> Rewrite c HermitM CoreProg-alphaConsRecIdsWith = andR . map (uncurry alphaConsRecId)---- | Rename the identifiers bound in the top-level binding at the head of the program with the given list of suggested names.-alphaConsWith :: (ExtendPath c Crumb, AddBindings c) => [TH.Name] -> Rewrite c HermitM CoreProg-alphaConsWith []     = fail "At least one new name must be provided."-alphaConsWith (n:ns) = alphaConsNonRec n <+ (consRecIdsT >>= (alphaConsRecIdsWith . zip (n:ns)))---- -- | Rename the specified variables bound in the top-level binding at the head of the program.--- alphaConsIds :: [Id] -> Rewrite c m CoreProg--- alphaConsIds vs = alphaConsNonRecIds Nothing vs <+ alphaConsRecIdsWith (zip (repeat Nothing) vs)---- -- | Rename all identifiers bound in the top-level binding at the head of the program.--- alphaCons :: Rewrite c m CoreProg--- alphaCons = consIdsT >>= alphaConsIds----------------------------------------------------------------------------- -- | Rename all identifiers bound at the top-level.--- alphaProg :: Rewrite c m CoreProg--- alphaProg = progNilT ProgNil <+ (alphaCons >>> progConsAllR idR alphaProg)----------------------------------------------------------------------------- | Alpha rename any bindings at this node.  Note: does not rename case alternatives unless invoked on the alternative.-alpha :: (ExtendPath c Crumb, AddBindings c, BoundVars c) => Rewrite c HermitM Core-alpha = setFailMsg "Cannot alpha-rename here." $-           promoteExprR (alphaLam Nothing <+ alphaCaseBinder Nothing <+ alphaLet)-        <+ promoteAltR alphaAlt---------------------------------------------------------------------------wrongFormForAlpha :: String -> String-wrongFormForAlpha s = "Cannot alpha-rename, " ++ wrongExprForm s-------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Common.hs
@@ -1,275 +0,0 @@-{-# LANGUAGE CPP, ScopedTypeVariables, FlexibleContexts #-}---- | Note: this module should NOT export externals. It is for common---   transformations needed by the other primitive modules.-module Language.HERMIT.Primitive.Common-    ( -- * Utility Transformations-      applyInContextT-      -- ** Finding function calls.-    , callT-    , callPredT-    , callNameT-    , callSaturatedT-    , callNameG-    , callDataConT-    , callDataConNameT-    , callsR-    , callsT-      -- ** Collecting variables bound at a Node-    , progIdsT-    , consIdsT-    , consRecIdsT-    , consNonRecIdT-    , bindVarsT-    , nonRecVarT-    , recIdsT-    , defIdT-    , lamVarT-    , letVarsT-    , letRecIdsT-    , letNonRecVarT-    , caseVarsT-    , caseWildIdT-    , caseAltVarsT-    , altVarsT-      -- ** Finding variables bound in the Context-    , boundVarsT-    , findBoundVarT-    , findIdT-    , findId-      -- ** Miscallaneous-    , wrongExprForm-    , nodups-    , mapAlts-    )--where--import GhcPlugins--import Data.List-import Data.Monoid-import qualified Data.Set as S--import Control.Monad(liftM)--import Language.HERMIT.Kure-import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.GHC--import qualified Language.Haskell.TH as TH-import Language.Haskell.TH.Syntax (showName)------------------------------------------------------------------------------------ | Apply a transformation to a value in the current context.-applyInContextT :: Translate c m a b -> a -> Translate c m x b-applyInContextT t a = contextonlyT $ \ c -> apply t c a---- Note: this is the same as: return a >>> t------------------------------------------------------------------------------------ | Lift GHC's collectArgs-callT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])-callT = contextfreeT $ \ e -> case e of-                                Var {} -> return (e, [])-                                App {} -> return (collectArgs e)-                                _      -> fail "not an application or variable occurence."--callPredT :: Monad m => (Id -> [CoreExpr] -> Bool) -> Translate c m CoreExpr (CoreExpr, [CoreExpr])-callPredT p = do-    call@(Var i, args) <- callT-    guardMsg (p i args) "predicate failed."-    return call---- | Succeeds if we are looking at an application of given function---   returning zero or more arguments to which it is applied.-callNameT :: MonadCatch m => TH.Name -> Translate c m CoreExpr (CoreExpr, [CoreExpr])-callNameT nm = setFailMsg ("callNameT: not a call to " ++ show nm) $-    callPredT (const . cmpTHName2Var nm)---- | Succeeds if we are looking at a fully saturated function call.-callSaturatedT :: Monad m => Translate c m CoreExpr (CoreExpr, [CoreExpr])-callSaturatedT = callPredT (\ i args -> idArity i == length args)--- TODO: probably better to calculate arity based on Id's type, as---       idArity is conservatively set to zero by default.---- | Succeeds if we are looking at an application of given function-callNameG :: MonadCatch m => TH.Name -> Translate c m CoreExpr ()-callNameG nm = prefixFailMsg "callNameG failed: " $ callNameT nm >>= \_ -> constT (return ())---- | Succeeds if we are looking at an application of a data constructor.-callDataConT :: MonadCatch m => Translate c m CoreExpr (DataCon, [Type], [CoreExpr])-callDataConT = prefixFailMsg "callDataConT failed:" $-#if __GLASGOW_HASKELL__ > 706-    do mb <- contextfreeT $ \ e -> let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- S.toList (coreExprFreeVars e) ])-                                   in return $ exprIsConApp_maybe (in_scope, idUnfolding) e-       maybe (fail "not a datacon application.") return mb-#else-    contextfreeT (return . exprIsConApp_maybe idUnfolding)-        >>= maybe (fail "not a datacon application.") return-#endif---- | Succeeds if we are looking at an application of a named data constructor.-callDataConNameT :: MonadCatch m => TH.Name -> Translate c m CoreExpr (DataCon, [Type], [CoreExpr])-callDataConNameT nm = do-    res@(dc,_,_) <- callDataConT-    guardMsg (cmpTHName2Name nm (dataConName dc)) "wrong datacon."-    return res---- | Apply a rewrite to all applications of a given function in a top-down manner, pruning on success.-callsR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Rewrite c m CoreExpr -> Rewrite c m Core-callsR nm rr = prunetdR (promoteExprR $ callNameG nm >> rr)---- | Apply a translate to all applications of a given function in a top-down manner,---   pruning on success, collecting the results.-callsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Translate c m CoreExpr b -> Translate c m Core [b]-callsT nm t = collectPruneT (promoteExprT $ callNameG nm >> t)------------------------------------------------------------------------------------ | List all identifiers bound at the top-level in a program.-progIdsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreProg [Id]-progIdsT = progNilT [] <+ progConsT bindVarsT progIdsT (++)---- | List the identifiers bound by the top-level binding group at the head of the program.-consIdsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreProg [Id]-consIdsT = progConsT bindVarsT mempty (\ vs () -> vs)---- | List the identifiers bound by a recursive top-level binding group at the head of the program.-consRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg [Id]-consRecIdsT = progConsT recIdsT mempty (\ vs () -> vs)---- | Return the identifier bound by a non-recursive top-level binding at the head of the program.-consNonRecIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreProg Id-consNonRecIdT = progConsT nonRecVarT mempty (\ v () -> v)---- | List all variables bound in a binding group.-bindVarsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreBind [Var]-bindVarsT = liftM return nonRecVarT <+ recIdsT---- | Return the variable bound by a non-recursive let expression.-nonRecVarT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreBind Var-nonRecVarT = nonRecT idR mempty (\ v () -> v)---- | List all identifiers bound in a recursive binding group.-recIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreBind [Id]-recIdsT = recT (\ _ -> defIdT) id---- | Return the identifier bound by a recursive definition.-defIdT :: (ExtendPath c Crumb, Monad m) => Translate c m CoreDef Id-defIdT = defT idR mempty (\ v () -> v)---- | Return the variable bound by a lambda expression.-lamVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var-lamVarT = lamT idR mempty (\ v () -> v)---- | List the variables bound by a let expression.-letVarsT :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m CoreExpr [Var]-letVarsT = letT bindVarsT mempty (\ vs () -> vs)---- | List the identifiers bound by a recursive let expression.-letRecIdsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Id]-letRecIdsT = letT recIdsT mempty (\ vs () -> vs)---- | Return the variable bound by a non-recursive let expression.-letNonRecVarT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Var-letNonRecVarT = letT nonRecVarT mempty (\ v () -> v)---- | List all variables bound by a case expression (in the alternatives and the wildcard binder).-caseVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [Var]-caseVarsT = caseT mempty idR mempty (\ _ -> altVarsT) (\ () v () vss -> v : nub (concat vss))---- | Return the case wildcard binder.-caseWildIdT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr Id-caseWildIdT = caseT mempty idR mempty (\ _ -> idR) (\ () i () _ -> i)---- | List the variables bound by all alternatives in a case expression.-caseAltVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreExpr [[Var]]-caseAltVarsT = caseT mempty mempty mempty (\ _ -> altVarsT) (\ () () () vss -> vss)---- | List the variables bound by a case alternative.-altVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreAlt [Var]-altVarsT = altT mempty (\ _ -> idR) mempty (\ () vs () -> vs)------------------------------------------------------------------------------------ Need a better error type so that we can factor out the repetition.---- | Lifted version of 'boundVars'.-boundVarsT :: (BoundVars c, Monad m) => Translate c m a (S.Set Var)-boundVarsT = contextonlyT (return . boundVars)---- | Find the unique variable bound in the context that matches the given name, failing if it is not unique.-findBoundVarT :: (BoundVars c, MonadCatch m) => TH.Name -> Translate c m a Var-findBoundVarT nm = prefixFailMsg ("Cannot resolve name " ++ showName nm ++ ", ") $-                        do c <- contextT-                           case findBoundVars nm c of-                             []         -> fail "no matching variables in scope."-                             [v]        -> return v-                             _ : _ : _  -> fail "multiple matching variables in scope."---- | Lookup the name in the context first, then, failing that, in GHC's global reader environment.-findIdT :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m, MonadCatch m) => TH.Name -> Translate c m a Id-findIdT nm = prefixFailMsg ("Cannot resolve name " ++ showName nm ++ ", ") $-             contextonlyT (findId nm)--findId :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m) => TH.Name -> c -> m Id-findId nm c = case findBoundVars nm c of-                []         -> findIdMG nm c-                [v]        -> return v-                _ : _ : _  -> fail "multiple matching variables in scope."--findIdMG :: (BoundVars c, HasGlobalRdrEnv c, HasDynFlags m, MonadThings m) => TH.Name -> c -> m Id-findIdMG nm c =-    case filter isValName $ findNamesFromTH (hermitGlobalRdrEnv c) nm of-      []  -> findIdBuiltIn nm-      [n] -> lookupId n-      ns  -> do dynFlags <- getDynFlags-                fail $ "multiple matches found:\n" ++ intercalate ", " (map (showPpr dynFlags) ns)--findIdBuiltIn :: forall m. Monad m => TH.Name -> m Id-findIdBuiltIn = go . showName-    where go ":"     = dataConId consDataCon-          go "[]"    = dataConId nilDataCon--          go "True"  = return trueDataConId-          go "False" = return falseDataConId--          go "<"     = return ltDataConId-          go "=="    = return eqDataConId-          go ">"     = return gtDataConId--          go "I#"    = dataConId intDataCon--          go "()"    = return unitDataConId-          -- TODO: add more as needed-          --       http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/TysWiredIn.html-          go _   = fail "variable not in scope."--          dataConId :: DataCon -> m Id-          dataConId = return . dataConWorkId------------------------------------------------------------------------------------ | Constructs a common error message.---   Argument 'String' should be the desired form of the expression.-wrongExprForm :: String -> String-wrongExprForm form = "Expression does not have the form: " ++ form------------------------------------------------------------------------------------ | Determine if a list contains no duplicated elements.-nodups :: Eq a => [a] -> Bool-nodups as = length as == length (nub as)----------------------------------------------------------------------------------mapAlts :: (CoreExpr -> CoreExpr) -> [CoreAlt] -> [CoreAlt]-mapAlts f alts = [ (ac, vs, f e) | (ac, vs, e) <- alts ]--------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Debug.hs
@@ -1,53 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-module Language.HERMIT.Primitive.Debug-       ( -- * Debugging Primitives-         externals-       , bracketR-       , observeR-       , observeFailureR-       , traceR-       )-where--import Control.Arrow--import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.Monad---- | Exposed debugging 'External's.-externals :: [External]-externals = map (.+ Debug)-         [ external "trace" (traceR :: String -> RewriteH Core)-                [ "give a side-effect message as output when processing this command" ]-         , external "observe" (observeR :: String -> RewriteH Core)-                [ "give a side-effect message as output, and observe the value being processed" ]-         , external "observe-failure" (observeFailureR :: String -> RewriteH Core -> RewriteH Core)-                [ "give a side-effect message if the rewrite fails, including the failing input" ]-         , external "bracket" (bracketR :: String -> RewriteH Core -> RewriteH Core)-                [ "if given rewrite succeeds, see its input and output" ]-         ]---- | If the 'Rewrite' fails, print out the 'Core', with a message.-observeFailureR :: Injection a Core => String -> RewriteH a -> RewriteH a-observeFailureR str m = m <+ observeR str---- | Print out the 'Core', with a message.-observeR :: Injection a Core => String -> RewriteH a-observeR msg = extractR $ sideEffectR $ \ cxt core ->-        sendDebugMessage $ DebugCore msg cxt core---- | Just say something, every time the rewrite is done.-traceR :: String -> RewriteH a-traceR msg = sideEffectR $ \ _ _ -> sendDebugMessage $ DebugTick msg---- | Show before and after a rewrite.-bracketR :: Injection a Core => String -> RewriteH a -> RewriteH a-bracketR msg rr = do-    -- Be careful to only run the rr once, in case it has side effects.-    (e,r) <- idR &&& attemptM rr-    either fail (\ e' -> do _ <- return e >>> observeR before-                            return e' >>> observeR after) r-    where before = msg ++ " (before)"-          after  = msg ++ " (after)"--- attemptM :: MonadCatch m => m a -> m (Either String a)
− src/Language/HERMIT/Primitive/FixPoint.hs
@@ -1,407 +0,0 @@-module Language.HERMIT.Primitive.FixPoint-       ( -- * Operations on the Fixed Point Operator (fix)-         -- | Note that many of these operations require 'Data.Function.fix' to be in scope.-         Language.HERMIT.Primitive.FixPoint.externals-         -- ** Rewrites and BiRewrites on Fixed Points-       , fixIntro-       , fixComputationRule-       , rollingRule-       )-where--import GhcPlugins as GHC hiding (varName)--import Control.Applicative-import Control.Arrow--import Data.Monoid (mempty)--import Language.HERMIT.Core-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.AlphaConversion-import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.GHC-import Language.HERMIT.Primitive.Local-import Language.HERMIT.Primitive.Navigation-import Language.HERMIT.Primitive.New -- TODO: Sort out heirarchy-import Language.HERMIT.Primitive.Unfold--import qualified Language.Haskell.TH as TH-------------------------------------------------------------------------------------------------------- | Externals for manipulating fixed points, and for the worker/wrapper transformation.-externals ::  [External]-externals = map (.+ Experiment)-         [ external "fix-intro" (promoteDefR fixIntro :: RewriteH Core)-                [ "rewrite a recursive binding into a non-recursive binding using fix"-                ] .+ Introduce .+ Context-         , external "fix-computation" ((promoteExprBiR fixComputationRule) :: BiRewriteH Core)-                [ "Fixed-Point Computation Rule",-                  "fix t f  <==>  f (fix t f)"-                ]-         , external "rolling-rule" ((promoteExprBiR rollingRule) :: BiRewriteH Core)-                [ "Rolling Rule",-                  "fix tyA (\\ a -> f (g a))  <==>  f (fix tyB (\\ b -> g (f b))"-                ]-         -- , external "fix-spec" (promoteExprR fixSpecialization :: RewriteH Core)-         --        [ "specialize a fix with a given argument"] .+ Shallow-         , external "ww-factorisation" ((\ wrap unwrap -> promoteExprBiR $ workerWrapperFac wrap unwrap) :: CoreString -> CoreString -> BiRewriteH Core)-                [ "Worker/Wrapper Factorisation",-                  "For any \"f :: a -> a\", and given \"wrap :: b -> a\" and \"unwrap :: a -> b\" as arguments, then",-                  "fix tyA f  <==>  wrap (fix tyB (\\ b -> unwrap (f (wrap b))))",-                  "Note: the pre-condition \"fix tyA (\\ a -> wrap (unwrap (f a))) == fix tyA f\" is expected to hold."-                ] .+ Introduce .+ Context .+ PreCondition-         , external "ww-fusion" ((\ wrap unwrap work -> promoteExprBiR $ workerWrapperFusion wrap unwrap work) :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)-                [ "Worker/Wrapper Fusion",-                  "Given \"wrap :: b -> a\", \"unwrap :: a -> b\" and \"work :: b\" as arguments, then",-                  "unwrap (wrap work)  <==>  work",-                  "Note: the pre-conditions \"fix tyA (\\ a -> wrap (unwrap (f a))) == fix tyA f\"",-                  "                     and \"work == fix (\\ b -> unwrap (f (wrap)))\" are expected to hold."-                ] .+ Introduce .+ Context .+ PreCondition-         , external "ww-split" ((\ wrap unwrap -> promoteDefR $ workerWrapperSplit wrap unwrap) :: CoreString -> CoreString -> RewriteH Core)-                [ "Worker/Wrapper Split",-                  "For any \"g :: a\", and given \"wrap :: b -> a\" and \"unwrap :: a -> b\" as arguments, then",-                  "g = expr  ==>  g = let f = \\ g -> expr",-                  "                    in let work = unwrap (f (wrap work))",-                  "                        in wrap work",-                  "Note: the pre-condition \"fix a (wrap . unwrap . f) == fix a f\" is expected to hold."-                ] .+ Introduce .+ Context .+ PreCondition-         , external "ww-split-param" ((\ n wrap unwrap -> promoteDefR $ workerWrapperSplitParam n wrap unwrap) :: Int -> CoreString -> CoreString -> RewriteH Core)-                [ "Worker/Wrapper Split - Type Paramater Variant",-                  "For any \"g :: forall t1 t2 .. tn . a\", and given \"wrap :: forall t1 t2 .. tn . b -> a\" and \"unwrap :: forall t1 t2 .. tn . a -> b\" as arguments, then",-                  "g = expr  ==>  g = \\ t1 t2 .. tn -> let f = \\ g -> expr t1 t2 .. tn",-                  "                                      in let work = unwrap t1 t2 .. tn (f (wrap t1 t2  ..tn work))",-                  "                                          in wrap t1 t2 .. tn work"-                ] .+ Introduce .+ Context .+ PreCondition .+ TODO .+ Experiment-         , external "ww-assumption-A" ((\ wrap unwrap -> promoteExprBiR $ wwA wrap unwrap) :: CoreString -> CoreString -> BiRewriteH Core)-                [ "Worker/Wrapper Assumption A",-                  "For a \"wrap :: b -> a\" and an \"unwrap :: b -> a\", then",-                  "wrap (unwrap x)  <==>  x",-                  "Note: only use this if it's true!"-                ] .+ Context .+ PreCondition-         , external "ww-assumption-B" ((\ wrap unwrap f -> promoteExprBiR $ wwB wrap unwrap f) :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)-                [ "Worker/Wrapper Assumption B",-                  "For a \"wrap :: b -> a\", an \"unwrap :: b -> a\", and an \"f :: a -> a\" then",-                  "wrap (unwrap (f x))  <==>  f x",-                  "Note: only use this if it's true!"-                ] .+ Context .+ PreCondition-         , external "ww-assumption-C" ((\ wrap unwrap f -> promoteExprBiR $ wwC wrap unwrap f) :: CoreString -> CoreString -> CoreString -> BiRewriteH Core)-                [ "Worker/Wrapper Assumption C",-                  "For a \"wrap :: b -> a\", an \"unwrap :: b -> a\", and an \"f :: a -> a\" then",-                  "fix t (\\ x -> wrap (unwrap (f x)))  <==>  fix t f",-                  "Note: only use this if it's true!"-                ] .+ Context .+ PreCondition-         ]-------------------------------------------------------------------------------------------------------- |  @f = e@   ==\>   @f = fix (\\ f -> e)@-fixIntro :: RewriteH CoreDef-fixIntro = prefixFailMsg "fix introduction failed: " $-           do Def f _ <- idR-              f' <- constT $ cloneVarH id f-              Def f <$> (mkFix =<< (defT mempty (extractR $ substR f $ varToCoreExpr f') (\ () e' -> Lam f' e')))-------------------------------------------------------------------------------------------------------- | @fix ty f@  \<==\>  @f (fix ty f)@-fixComputationRule :: BiRewriteH CoreExpr-fixComputationRule = bidirectional computationL computationR-  where-    computationL :: RewriteH CoreExpr-    computationL = prefixFailMsg "fix computation rule failed: " $-                   do (_,f) <- isFixExpr-                      fixf  <- idR-                      return (App f fixf)--    computationR :: RewriteH CoreExpr-    computationR = prefixFailMsg "fix computation rule failed: " $-                   do App f fixf <- idR-                      (_,f') <- isFixExpr <<< constant fixf-                      guardMsg (exprEqual f f') "external function does not match internal expression"-                      return fixf----- | @fix tyA (\\ a -> f (g a))@  \<==\>  @f (fix tyB (\\ b -> g (f b))@-rollingRule :: BiRewriteH CoreExpr-rollingRule = bidirectional rollingRuleL rollingRuleR-  where-    rollingRuleL :: RewriteH CoreExpr-    rollingRuleL = prefixFailMsg "rolling rule failed: " $-                   withPatFailMsg wrongFixBody $-                   do (tyA, Lam a (App f (App g (Var a')))) <- isFixExpr-                      guardMsg (a == a') wrongFixBody-                      (tyA',tyB) <- funsWithInverseTypes g f-                      guardMsg (eqType tyA tyA') "Type mismatch: this shouldn't have happened, report this as a bug."-                      res <- rollingRuleResult tyB g f-                      return (App f res)--    rollingRuleR :: RewriteH CoreExpr-    rollingRuleR = prefixFailMsg "(reversed) rolling rule failed: " $-                   withPatFailMsg "not an application." $-                   do App f fx <- idR-                      withPatFailMsg wrongFixBody $-                        do (tyB, Lam b (App g (App f' (Var b')))) <- isFixExpr <<< constant fx-                           guardMsg (b == b') wrongFixBody-                           guardMsg (exprEqual f f') "external function does not match internal expression"-                           (tyA,tyB') <- funsWithInverseTypes g f-                           guardMsg (eqType tyB tyB') "Type mismatch: this shouldn't have happened, report this as a bug."-                           rollingRuleResult tyA f g--    rollingRuleResult :: Type -> CoreExpr -> CoreExpr -> TranslateH z CoreExpr-    rollingRuleResult ty f g = do x <- constT (newIdH "x" ty)-                                  mkFix (Lam x (App f (App g (Var x))))--    wrongFixBody :: String-    wrongFixBody = "body of fix does not have the form: Lam v (App f (App g (Var v)))"-------------------------------------------------------------------------------------------------------- ironically, this is an instance of worker/wrapper itself.---- fixSpecialization :: RewriteH CoreExpr--- fixSpecialization = do----         -- fix (t::*) (f :: t -> t) (a :: t) :: t---         App (App (App (Var fixId) (Type _)) _) _ <- idR----         guardIsFixId fixId----         let r :: RewriteH CoreExpr---             r = multiEtaExpand [TH.mkName "f",TH.mkName "a"]----             sub :: RewriteH Core---             sub = pathR [0,1] (promoteR r)----         App (App (App (Var fx) (Type t))---                  (Lam _ (Lam v2 (App (App e _) _a2)))---             )---             (Type t2) <- extractR sub -- In normal form now----         constT $ do let t' = applyTy t t2----                     v3 <- newIdH "f" t'---                     v4 <- newTyVarH "a" (tyVarKind v2)----                     -- f' :: \/ a -> T [a] -> (\/ b . T [b])---                     let f' = Lam v4 (Cast (Var v3) (mkUnsafeCo t' (applyTy t (mkTyVarTy v4))))---                         e' = Lam v3 (App (App e f') (Type t2))----                     return $ App (App (Var fx) (Type t')) e'--------------------------------------------------------------------------------------------------------- | For any @f :: a -> a@, and given @wrap :: b -> a@ and @unwrap :: a -> b@ as arguments, then---   @fix tyA f@  \<==\>  @wrap (fix tyB (\\ b -> unwrap (f (wrap b))))@-workerWrapperFacBR :: CoreExpr -> CoreExpr -> BiRewriteH CoreExpr-workerWrapperFacBR wrap unwrap = beforeBiR (wrapUnwrapTypes wrap unwrap)-                                           (\ (tyA,tyB) -> bidirectional (wwL tyA tyB) wwR)-  where-    wwL :: Type -> Type -> RewriteH CoreExpr-    wwL tyA tyB = prefixFailMsg "worker/wrapper factorisation failed: " $-                  do (tA,f)    <- isFixExpr-                     guardMsg (eqType tyA tA) ("wrapper/unwrapper types do not match fix body type.")-                     b  <- constT (newIdH "x" tyB)-                     fx <- mkFix (Lam b (App unwrap (App f (App wrap (Var b)))))-                     return $ App wrap fx--    wwR :: RewriteH CoreExpr-    wwR = prefixFailMsg "(reverse) worker/wrapper factorisation failed: " $-          withPatFailMsg "not an application." $-          do App wrap2 fx <- idR-             withPatFailMsg wrongFixBody $-               do (_, Lam b (App unwrap1 (App f (App wrap1 (Var b'))))) <- isFixExpr <<< constant fx-                  guardMsg (b == b') wrongFixBody-                  guardMsg (exprEqual wrap wrap2) "given wrapper does not match applied function."-                  guardMsg (exprEqual wrap wrap1) "given wrapper does not match wrapper in body of fix."-                  guardMsg (exprEqual unwrap unwrap1) "given unwrapper does not match unwrapper in body of fix."-                  mkFix f--    wrongFixBody :: String-    wrongFixBody = "body of fix does not have the form Lam b (App unwrap (App f (App wrap (Var b))))"---- | For any @f :: a -> a@, and given @wrap :: b -> a@ and @unwrap :: a -> b@ as arguments, then---   @fix tyA f@  \<==\>  @wrap (fix tyB (\\ b -> unwrap (f (wrap b))))@-workerWrapperFac :: CoreString -> CoreString -> BiRewriteH CoreExpr-workerWrapperFac = parse2beforeBiR workerWrapperFacBR-------------------------------------------------------------------------------------------------------- | Given @wrap :: b -> a@, @unwrap :: a -> b@ and @work :: b@ as arguments, then---   @unwrap (wrap work)@  \<==\>  @work@-workerWrapperFusionBR :: CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr-workerWrapperFusionBR wrap unwrap work = beforeBiR (prefixFailMsg "worker/wrapper fusion failed: " $-                                                    do (_,tyB) <- wrapUnwrapTypes wrap unwrap-                                                       guardMsg (exprType work `eqType` tyB) "type of worker does not match types of wrap/unwrap."-                                                   )-                                                   (\ () -> bidirectional fusL fusR)-  where-    fusL :: RewriteH CoreExpr-    fusL = prefixFailMsg "worker/wrapper fusion failed: " $-           withPatFailMsg (wrongExprForm "App unwrap (App wrap work)") $-           do App unwrap' (App wrap' work') <- idR-              guardMsg (exprEqual wrap wrap') "given wrapper does not match wrapper in expression."-              guardMsg (exprEqual unwrap unwrap') "given unwrapper does not match unwrapper in expression."-              guardMsg (exprEqual work work') "given worker function does not worker in expression."-              return work--    fusR :: RewriteH CoreExpr-    fusR = prefixFailMsg "(reverse) worker/wrapper fusion failed: " $-           do work' <- idR-              guardMsg (exprEqual work work') "given worker function does not match expression."-              return $ App unwrap (App wrap work)---- | Given @wrap :: b -> a@, @unwrap :: a -> b@ and @work :: b@ as arguments, then---   @unwrap (wrap work)@  \<==\>  @work@-workerWrapperFusion :: CoreString -> CoreString -> CoreString -> BiRewriteH CoreExpr-workerWrapperFusion = parse3beforeBiR workerWrapperFusionBR-------------------------------------------------------------------------------------------------------- | \\ wrap unwrap ->  (@g = expr@  ==>  @g = let f = \\ g -> expr in let work = unwrap (f (wrap work)) in wrap work)@-workerWrapperSplitR :: CoreExpr -> CoreExpr -> RewriteH CoreDef-workerWrapperSplitR wrap unwrap =-  let f    = TH.mkName "f"-      w    = TH.mkName "w"-      work = TH.mkName "work"-      fx   = TH.mkName "fix"-   in-      fixIntro >>> defAllR idR ( appAllR idR (letIntro f)-                                  >>> letFloatArg-                                  >>> letAllR idR ( forewardT (workerWrapperFacBR wrap unwrap)-                                                     >>> appAllR idR (letIntro w)-                                                     >>> letFloatArg-                                                     >>> letNonRecAllR idR (unfoldNameR fx >>> alphaLetWith [work] >>> extractR simplifyR) idR-                                                     >>> letSubstR-                                                     >>> letFloatArg-                                                  )-                               )---- | \\ wrap unwrap ->  (@g = expr@  ==>  @g = let f = \\ g -> expr in let work = unwrap (f (wrap work)) in wrap work)@-workerWrapperSplit :: CoreString -> CoreString -> RewriteH CoreDef-workerWrapperSplit wrapS unwrapS = (parseCoreExprT wrapS &&& parseCoreExprT unwrapS) >>= uncurry workerWrapperSplitR---- | As 'workerWrapperSplit' but performs the static-argument transformation for @n@ type paramaters first, providing these types as arguments to all calls of wrap and unwrap.---   This is useful if the expression, and wrap and unwrap, all have a @forall@ type.-workerWrapperSplitParam :: Int -> CoreString -> CoreString -> RewriteH CoreDef-workerWrapperSplitParam 0 = workerWrapperSplit-workerWrapperSplitParam n = \ wrapS unwrapS -> prefixFailMsg "worker/wrapper split (forall variant) failed: " $-                                               do guardMsg (n == 1) "currently only supports 1 type paramater."-                                                  withPatFailMsg "right-hand-side of definition does not have the form: Lam t e" $-                                                    do Def _ (Lam t _) <- idR-                                                       guardMsg (isTyVar t) "first argument is not a type."-                                                       let splitAtDefR :: RewriteH Core-                                                           splitAtDefR = do p <- considerConstructT Definition-                                                                            pathR p $ promoteR $ do wrap   <- parseCoreExprT wrapS-                                                                                                    unwrap <- parseCoreExprT unwrapS-                                                                                                    let ty = Type (TyVarTy t)-                                                                                                    workerWrapperSplitR (App wrap ty) (App unwrap ty)-                                                       staticArg >>> extractR splitAtDefR-------------------------------------------------------------------------------------------------------- | @wrap (unwrap x)@  \<==\>  @x@-wwAssA :: CoreExpr -> CoreExpr -> BiRewriteH CoreExpr-wwAssA wrap unwrap = beforeBiR (wrapUnwrapTypes wrap unwrap) (\ (tyA,_) -> bidirectional wwAL (wwAR tyA))-  where-    wwAL :: RewriteH CoreExpr-    wwAL = withPatFailMsg (wrongExprForm "App wrap (App unwrap x)") $-           do App wrap' (App unwrap' x) <- idR-              guardMsg (exprEqual wrap wrap')     "given wrapper does not match wrapper in expression."-              guardMsg (exprEqual unwrap unwrap') "given unwrapper does not match unwrapper in expression."-              return x--    wwAR :: Type -> RewriteH CoreExpr-    wwAR tyA = do x <- idR-                  guardMsg (exprType x `eqType` tyA) "type of expression does not match types of wrap/unwrap."-                  return $ App wrap (App unwrap x)---- | @wrap (unwrap x)@  \<==\>  @x@-wwA :: CoreString -> CoreString -> BiRewriteH CoreExpr-wwA = parse2beforeBiR wwAssA----- | @wrap (unwrap (f x))@  \<==\>  @f x@-wwAssB :: CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr-wwAssB wrap unwrap f = bidirectional wwBL wwBR-  where-    assA :: BiRewriteH CoreExpr-    assA = wwAssA wrap unwrap--    wwBL :: RewriteH CoreExpr-    wwBL = withPatFailMsg (wrongExprForm "App wrap (App unwrap (App f x))") $-           do App _ (App _ (App f' _)) <- idR-              guardMsg (exprEqual f f') "given body function does not match expression."-              forewardT assA--    wwBR :: RewriteH CoreExpr-    wwBR = withPatFailMsg (wrongExprForm "App f x") $-           do App f' _ <- idR-              guardMsg (exprEqual f f') "given body function does not match expression."-              backwardT assA---- | @wrap (unwrap (f x))@  \<==\>  @f x@-wwB :: CoreString -> CoreString -> CoreString -> BiRewriteH CoreExpr-wwB = parse3beforeBiR wwAssB----- | @fix t (\ x -> wrap (unwrap (f x)))@  \<==\>  @fix t f@-wwAssC :: CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH CoreExpr-wwAssC wrap unwrap f = beforeBiR isFixExpr (\ _ -> bidirectional wwCL wwCR)-  where-    assB :: BiRewriteH CoreExpr-    assB = wwAssB wrap unwrap f--    wwCL :: RewriteH CoreExpr-    wwCL = appAllR idR (lamAllR idR (forewardT assB) >>> etaReduce)--    wwCR :: RewriteH CoreExpr-    wwCR = appAllR idR (etaExpand "x" >>> lamAllR idR (backwardT assB))---- | @fix t (\ x -> wrap (unwrap (f x)))@  \<==\>  @fix t f@-wwC :: CoreString -> CoreString -> CoreString -> BiRewriteH CoreExpr-wwC = parse3beforeBiR wwAssC-------------------------------------------------------------------------------------------------------- | Check that the expression has the form "fix t (f :: t -> t)", returning "t" and "f".-isFixExpr :: TranslateH CoreExpr (Type,CoreExpr)-isFixExpr = withPatFailMsg (wrongExprForm "fix t f") $ -- fix :: forall a. (a -> a) -> a-            do App (App (Var fixId) (Type ty)) f <- idR-               fixId' <- findFixId-               guardMsg (fixId == fixId') (var2String fixId ++ " does not match " ++ fixLocation)-               return (ty,f)--wrapUnwrapTypes :: MonadCatch m => CoreExpr -> CoreExpr -> m (Type,Type)-wrapUnwrapTypes wrap unwrap = setFailMsg "given expressions have the wrong types to form a valid wrap/unwrap pair." $-                              funsWithInverseTypes unwrap wrap-------------------------------------------------------------------------------------------------------- | f  ==>  fix f-mkFix :: CoreExpr -> TranslateH z CoreExpr-mkFix f = do t <- endoFunType f-             fixId <- findFixId-             return $ mkCoreApps (varToCoreExpr fixId) [Type t, f]--fixLocation :: String-fixLocation = "Data.Function.fix"--findFixId :: TranslateH a Id-findFixId = findIdT (TH.mkName fixLocation)------------------------------------------------------------------------------------------------------parse2beforeBiR :: (CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> BiRewriteH a-parse2beforeBiR f s1 s2 = beforeBiR (parseCoreExprT s1 &&& parseCoreExprT s2) (uncurry f)--parse3beforeBiR :: (CoreExpr -> CoreExpr -> CoreExpr -> BiRewriteH a) -> CoreString -> CoreString -> CoreString -> BiRewriteH a-parse3beforeBiR f s1 s2 s3 = beforeBiR ((parseCoreExprT s1 &&& parseCoreExprT s2) &&& parseCoreExprT s3) ((uncurry.uncurry) f)----------------------------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Fold.hs
@@ -1,153 +0,0 @@-module Language.HERMIT.Primitive.Fold-    ( -- * Fold/Unfold Transformation-      externals-    , foldR-    , stashFoldR-    , stashFoldAnyR-    )--where--import GhcPlugins hiding (empty)--import Control.Applicative-import Control.Monad--import Data.List (intercalate)-import qualified Data.Map as Map--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.GHC hiding (externals)-import Language.HERMIT.Primitive.Inline hiding (externals)--import qualified Language.Haskell.TH as TH--import Prelude hiding (exp)----------------------------------------------------------------------------externals :: [External]-externals =-    [ external "fold" (promoteExprR . foldR :: TH.Name -> RewriteH Core)-        [ "fold a definition"-        , ""-        , "double :: Int -> Int"-        , "double x = x + x"-        , ""-        , "5 + 5 + 6"-        , "any-bu (fold 'double)"-        , "double 5 + 6"-        , ""-        , "Note: due to associativity, if you wanted to fold 5 + 6 + 6, "-        , "you first need to apply an associativity rewrite." ]  .+ Context .+ Deep-    , external "fold" (promoteExprR . stashFoldR :: Label -> RewriteH Core)-        [ "Fold a remembered definition." ]                      .+ Context .+ Deep-    , external "fold-any" (promoteExprR stashFoldAnyR :: RewriteH Core)-        [ "Attempt to fold any of the remembered definitions." ] .+ Context .+ Deep-    ]----------------------------------------------------------------------------stashFoldR :: ReadBindings c => Label -> Rewrite c HermitM CoreExpr-stashFoldR label = prefixFailMsg "Fold failed: " $-    translate $ \ c e -> do-        Def i rhs <- lookupDef label-        guardMsg (inScope c i) $ var2String i ++ " is not in scope.\n(A common cause of this error is trying to fold a recursive call while being in the body of a non-recursive definition.  This can be resolved by calling \"nonrec-to-rec\" on the non-recursive binding group.)"-        maybe (fail "no match.")-              return-              (fold i rhs e)--stashFoldAnyR :: ReadBindings c => Rewrite c HermitM CoreExpr-stashFoldAnyR = setFailMsg "Fold failed: no definitions could be folded." $-                catchesM =<< map stashFoldR <$> (Map.keys <$> constT getStash)--foldR :: ReadBindings c => TH.Name -> Rewrite c HermitM CoreExpr-foldR nm =  prefixFailMsg "Fold failed: " $-    translate $ \ c e -> do-        i <- case findBoundVars nm c of-                []  -> fail "cannot find name."-                [i] -> return i-                is  -> fail $ "multiple names match: " ++ intercalate ", " (map var2String is)-        (rhs,_d) <- getUnfolding False False i c-        maybe (fail "no match.") return (fold i rhs e)----------------------------------------------------------------------------fold :: Id -> CoreExpr -> CoreExpr -> Maybe CoreExpr-fold i lam exp = do-    let (vs,body) = collectBinders lam-        -- return Nothing if not equal, so sequence will fail below-        checkEqual :: Maybe CoreExpr -> Maybe CoreExpr -> Maybe CoreExpr-        checkEqual m1 m2 = ifM (exprEqual <$> m1 <*> m2) m1 Nothing--    al <- foldMatch vs [] body exp--    let m = Map.fromListWith checkEqual [(k,Just v) | (k,v) <- al ]--    es <- sequence [ join (Map.lookup v m) | v <- vs ]-    return $ mkCoreApps (varToCoreExpr i) es---- Note: Id in the concrete instance is first--- (not the Id found in the definition we are trying to fold).-addAlpha :: Id -> Id -> [(Id,Id)] -> [(Id,Id)]-addAlpha rId lId alphas | rId == lId = alphas-                        | otherwise  = (rId,lId) : alphas---- Note: return list can have duplicate keys, caller is responsible--- for checking that dupes refer to same expression-foldMatch :: [Var]          -- ^ vars that can unify with anything-          -> [(Id,Id)]      -- ^ alpha equivalences, wherever there is binding-                            --   note: we depend on behavior of lookup here, so new entries-                            --         should always be added to the front of the list so-                            --         we don't have to explicity remove them when shadowing occurs-          -> CoreExpr       -- ^ pattern we are matching on-          -> CoreExpr       -- ^ expression we are checking-          -> Maybe [(Var,CoreExpr)] -- ^ mapping of vars to expressions, or failure-foldMatch vs as (Var i) e | i `elem` vs = return [(i,e)]-                          | otherwise   = case e of-                                            Var i' | maybe False (==i) (lookup i' as) -> return [(i,e)]-                                                   | i == i' -> return []-                                            _                -> Nothing-foldMatch _  _ (Lit l) (Lit l') | l == l' = return []-foldMatch vs as (App e a) (App e' a') = do-    x <- foldMatch vs as e e'-    y <- foldMatch vs as a a'-    return (x ++ y)-foldMatch vs as (Lam v e) (Lam v' e') = foldMatch (filter (==v) vs) (addAlpha v' v as) e e'-foldMatch vs as (Let (NonRec v rhs) e) (Let (NonRec v' rhs') e') = do-    x <- foldMatch vs as rhs rhs'-    y <- foldMatch (filter (==v) vs) (addAlpha v' v as) e e'-    return (x ++ y)--- TODO: this depends on bindings being in the same order-foldMatch vs as (Let (Rec bnds) e) (Let (Rec bnds') e') | length bnds == length bnds' = do-    let vs' = filter (`elem` map fst bnds) vs-        as' = [ (v',v) | ((v,_),(v',_)) <- zip bnds bnds' ] ++ as-        bmatch (_,rhs) (_,rhs') = foldMatch vs' as' rhs rhs'-    x <- zipWithM bmatch bnds bnds'-    y <- foldMatch vs' as' e e'-    return (concat x ++ y)-foldMatch vs as (Tick t e) (Tick t' e') | t == t' = foldMatch vs as e e'-foldMatch vs as (Case s b ty alts) (Case s' b' ty' alts')-  | (eqType ty ty') && (length alts == length alts') = do-    let as' = addAlpha b' b as-    x <- foldMatch vs as' s s'-    let vs' = filter (/=b) vs-        altMatch (ac, is, e) (ac', is', e') | ac == ac' =-            foldMatch (filter (`notElem` is) vs') (zip is' is ++ as') e e'-        altMatch _ _ = Nothing-    y <- zipWithM altMatch alts alts'-    return (x ++ concat y)-foldMatch vs as (Cast e c)   (Cast e' c')  | coreEqCoercion c c' = foldMatch vs as e e'--- don't try to alpha type variables for now-foldMatch vs _  (Type t@(TyVarTy v)) e@(Type t') | v `elem` vs = return [(v,e)]-                                                 | eqType t t' = return []-                                                 | otherwise   = Nothing-foldMatch _ _   (Type t)     (Type t')     | eqType t t' = return []-foldMatch _ _   (Coercion c) (Coercion c') | coreEqCoercion c c' = return []-foldMatch _ _ _ _ = Nothing
− src/Language/HERMIT/Primitive/GHC.hs
@@ -1,611 +0,0 @@-{-# LANGUAGE CPP, FlexibleContexts, ScopedTypeVariables, LambdaCase #-}-module Language.HERMIT.Primitive.GHC-       ( -- * GHC-based Transformations-         -- | This module contains transformations that are reflections of GHC functions, or derived from GHC functions.-         externals-       , anyCallR-         -- ** Free Variables-       , coreExprFreeIds-       , coreExprFreeVars-       , typeFreeVars-       , freeIdsT-       , freeVarsT-       , freeTyVarsT-       , altFreeVarsT-       , altFreeVarsExclWildT-         -- ** Substitution-       , substR-       , substExprR-       , letSubstR-       , safeLetSubstR-       , safeLetSubstPlusR-         -- ** Equality-       , exprEqual-       , exprsEqual-       , coreEqual-         -- ** Utilities-       , inScope-       , showVars-       , rule-       , rules-       , equivalent-         -- ** Lifted GHC capabilities-       , lintExprT-       , lintProgramT-       , lintModuleT-       , specConstrR-       )-where--import GhcPlugins-import qualified Bag-import qualified CoreLint-import qualified OccurAnal-import IOEnv-import qualified SpecConstr--import Control.Arrow-import Control.Monad--import Data.Function (on)-import Data.List (intercalate,mapAccumL,deleteFirstsBy)-import Data.Monoid (mempty)-import Data.Set (Set, fromList, toList, (\\))--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.Debug hiding (externals)-import Language.HERMIT.Primitive.Navigation hiding (externals)--import qualified Language.Haskell.TH as TH------------------------------------------------------------------------------ | Externals that reflect GHC functions, or are derived from GHC functions.-externals :: [External]-externals =-         [ external "info" (info :: TranslateH CoreTC String)-                [ "display information about the current node." ]-         , external "let-subst" (promoteExprR letSubstR :: RewriteH Core)-                [ "Let substitution"-                , "(let x = e1 in e2) ==> (e2[e1/x])"-                , "x must not be free in e1." ]                           .+ Deep-         , external "safe-let-subst" (promoteExprR safeLetSubstR :: RewriteH Core)-                [ "Safe let substitution"-                , "let x = e1 in e2, safe to inline without duplicating work ==> e2[e1/x],"-                , "x must not be free in e1." ]                           .+ Deep .+ Eval .+ Bash-         , external "safe-let-subst-plus" (promoteExprR safeLetSubstPlusR :: RewriteH Core)-                [ "Safe let substitution"-                , "let { x = e1, ... } in e2, "-                , "  where safe to inline without duplicating work ==> e2[e1/x,...],"-                , "only matches non-recursive lets" ]  .+ Deep .+ Eval-         , external "free-ids" (promoteExprT freeIdsQuery :: TranslateH Core String)-                [ "List the free identifiers in this expression." ] .+ Query .+ Deep-         , external "deshadow-prog" (promoteProgR deShadowProgR :: RewriteH Core)-                [ "Deshadow a program." ] .+ Deep-         , external "apply-rule" (promoteExprR . rule :: String -> RewriteH Core)-                [ "apply a named GHC rule" ] .+ Shallow-         , external "apply-rule" (rules_help :: TranslateH Core String)-                [ "list rules that can be used" ] .+ Query-         , external "apply-rules" (promoteExprR . rules :: [String] -> RewriteH Core)-                [ "apply named GHC rules, succeeds if any of the rules succeed" ] .+ Shallow-         , external "compare-values" (compareValues ::  TH.Name -> TH.Name -> TranslateH Core ())-                ["compare the rhs of two values."] .+ Query .+ Predicate-         , external "add-rule" ((\ rule_name id_name -> promoteModGutsR (addCoreBindAsRule rule_name id_name)) :: String -> TH.Name -> RewriteH Core)-                ["add-rule \"rule-name\" <id> -- adds a new rule that freezes the right hand side of the <id>"]-                                        .+ Introduce-         , external "occur-analysis" (promoteExprR occurAnalyseExprR :: RewriteH Core)-                ["Performs dependency anlaysis on a CoreExpr.",-                 "This can be useful to simplify a recursive let to a non-recursive let."] .+ Deep-         , external "lintExpr" (promoteExprT lintExprT :: TranslateH Core String)-                ["Runs GHC's Core Lint, which typechecks the current expression."-                ,"Note: this can miss several things that a whole-module core lint will find."-                ,"For instance, running this on the RHS of a binding, the type of the RHS will"-                ,"not be checked against the type of the binding. Running on the whole let expression"-                ,"will catch that however."] .+ Deep .+ Debug .+ Query-         , external "lintProg" (promoteProgT lintProgramT :: TranslateH Core String)-                ["Runs GHC's Core Lint, which typechecks the top level list of bindings."] .+ Deep .+ Debug .+ Query-         , external "lintModule" (promoteModGutsT lintModuleT :: TranslateH Core String)-                ["Runs GHC's Core Lint, which typechecks the current module."] .+ Deep .+ Debug .+ Query-         , external "specConstr" (promoteModGutsR specConstrR :: RewriteH Core)-                ["Run GHC's SpecConstr pass, which performs call pattern specialization."] .+ Deep-         , external "any-call" (anyCallR :: RewriteH Core -> RewriteH Core)-                [ "any-call (.. unfold command ..) applies an unfold commands to all applications"-                , "preference is given to applications with more arguments" ] .+ Deep-         ]------------------------------------------------------------------------------ | Substitute all occurrences of a variable with an expression, in either a program or an expression.-substR :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Var -> CoreExpr -> Rewrite c m Core-substR v e = setFailMsg "Can only perform substitution on expressions or programs." $-             promoteExprR (substExprR v e) <+ promoteProgR (substTopBindR v e) <+ promoteAltR (substAltR v e)---- | Substitute all occurrences of a variable with an expression, in an expression.-substExprR :: Monad m => Var -> CoreExpr -> Rewrite c m CoreExpr-substExprR v e =  contextfreeT $ \ expr -> do-    -- The InScopeSet needs to include any free variables appearing in the-    -- expression to be substituted.  Constructing a NonRec Let expression-    -- to pass on to exprFeeVars takes care of this, but ...-    -- TODO Is there a better way to do this ???-    let emptySub = mkEmptySubst (mkInScopeSet (exprFreeVars (Let (NonRec v e) expr)))-    return $ substExpr (text "substR") (extendSubst emptySub v e) expr---- | Substitute all occurrences of a variable with an expression, in a program.-substTopBindR :: Monad m => Var -> CoreExpr -> Rewrite c m CoreProg-substTopBindR v e =  contextfreeT $ \ p -> do-    -- TODO.  Do we need to initialize the emptySubst with bindFreeVars?-    let emptySub =  emptySubst -- mkEmptySubst (mkInScopeSet (exprFreeVars exp))-    return $ bindsToProg $ snd (mapAccumL substBind (extendSubst emptySub v e) (progToBinds p))---- | Substitute all occurrences of a variable with an expression, in a case alternative.-substAltR :: (ExtendPath c Crumb, AddBindings c, Monad m) => Var -> CoreExpr -> Rewrite c m CoreAlt-substAltR v e = do (_, vs, _) <- idR-                   if v `elem` vs-                    then fail "variable is shadowed by a case-alternative constructor argument."-                    else altAllR idR (\ _ -> idR) (substExprR v e)---- | (let x = e1 in e2) ==> (e2[e1/x]),---   x must not be free in e1.-letSubstR :: MonadCatch m => Rewrite c m CoreExpr-letSubstR =  prefixFailMsg "Let substition failed: " $-             rewrite $ \ c expr -> case occurAnalyseExpr expr of-                                     Let (NonRec b be) e -> apply (substExprR b be) c e-                                     _ -> fail "expression is not a non-recursive Let."----- Neil: Commented this out as it's not (currently) used.---  Perform let-substitution the specified number of times.--- letSubstNR :: Int -> Rewrite c m Core--- letSubstNR 0 = idR--- letSubstNR n = childR 1 (letSubstNR (n - 1)) >>> promoteExprR letSubstR---- | This is quite expensive (O(n) for the size of the sub-tree).-safeLetSubstR :: (ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr-safeLetSubstR =  prefixFailMsg "Safe let-substition failed: " $-                 translate $ \ env expr ->-    let   -- Lit?-          safeBind (Var {})   = True-          safeBind (Lam {})   = True-          safeBind e@(App {}) =-                 case collectArgs e of-                   (Var f,args) -> arityOf env f > length (filter (not . isTyCoArg) args) -- Neil: I've changed this to "not . isTyCoArg" rather than "not . isTypeArg".  This may not be the right thing to do though.-                   (other,args) -> case collectBinders other of-                                     (bds,_) -> length bds > length args-          safeBind _          = False--          safeSubst NoOccInfo = False   -- unknown!-          safeSubst IAmDead   = True    -- DCE-          safeSubst (OneOcc inLam oneBr _) = not inLam && oneBr -- do not inline inside a lambda or if in multiple case branches-          safeSubst _ = False   -- strange case, like a loop breaker-   in case occurAnalyseExpr expr of-      -- By (our) definition, types are a trivial bind-      Let (NonRec b _) _-         | isTyVar b -> apply letSubstR env expr-      Let (NonRec b be) _-         | isId b && (safeBind be || safeSubst (occInfo (idInfo b)))-                     -> apply letSubstR env expr-         | otherwise -> fail "safety critera not met."-      _ -> fail "expression is not a non-recursive Let."---- | 'safeLetSubstPlusR' tries to inline a stack of bindings, stopping when reaches--- the end of the stack of lets.-safeLetSubstPlusR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m) => Rewrite c m CoreExpr-safeLetSubstPlusR = tryR (letT idR safeLetSubstPlusR Let) >>> safeLetSubstR----------------------------------------------------------------------------info :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, BoundVars c, HasDynFlags m, MonadCatch m) => Translate c m CoreTC String-info = do crumbs <- childrenT-          translate $ \ c coreTC -> do-            dynFlags <- getDynFlags-            let pa       = "Path: " ++ showCrumbs (snocPathToPath $ absPath c)-                node     = "Node: " ++ coreTCNode coreTC-                con      = "Constructor: " ++ coreTCConstructor coreTC-                children = "Children: " ++ showCrumbs crumbs-                bds      = "Bindings in Scope: " ++ show (map var2String $ toList $ boundVars c)-                extra    = case coreTC of-                             Core (ExprCore e)      -> ["Type or Kind: " ++ showPpr dynFlags (exprTypeOrKind e)] ++-                                                       ["Free Variables: " ++ showVars (toList $ coreExprFreeVars e)] ++-                                                       case e of-                                                         Var i -> ["Identifier Info: " ++ showIdInfo dynFlags i]-                                                         _     -> []-                             TyCo (TypeCore ty)     -> ["Kind: " ++ showPpr dynFlags (typeKind ty)]-                             TyCo (CoercionCore co) -> ["Kind: " ++ showPpr dynFlags (coercionType co) ] -- TODO: Revisit this, should we use coercionKind?-                             _                      -> []--            return (intercalate "\n" $ [pa,node,con,children,bds] ++ extra)--showIdInfo :: DynFlags -> Id -> String-showIdInfo dynFlags v = showSDoc dynFlags $ ppIdInfo v $ idInfo v--coreTCNode :: CoreTC -> String-coreTCNode (Core core)           = coreNode core-coreTCNode (TyCo TypeCore{})     = "Type"-coreTCNode (TyCo CoercionCore{}) = "Coercion"--coreNode :: Core -> String-coreNode (GutsCore _)  = "Module"-coreNode (ProgCore _)  = "Program"-coreNode (BindCore _)  = "Binding Group"-coreNode (DefCore _)   = "Recursive Definition"-coreNode (ExprCore _)  = "Expression"-coreNode (AltCore _)   = "Case Alternative"--coreTCConstructor :: CoreTC -> String-coreTCConstructor = \case-                       Core core              -> coreConstructor core-                       TyCo (TypeCore ty)     -> typeConstructor ty-                       TyCo (CoercionCore co) -> coercionConstructor co--coreConstructor :: Core -> String-coreConstructor (GutsCore _)     = "ModGuts"-coreConstructor (ProgCore prog)  = case prog of-                                     ProgNil      -> "ProgNil"-                                     ProgCons _ _ -> "ProgCons"-coreConstructor (BindCore bnd)   = case bnd of-                                     Rec _      -> "Rec"-                                     NonRec _ _ -> "NonRec"-coreConstructor (DefCore _)      = "Def"-coreConstructor (AltCore _)      = "(,,)"-coreConstructor (ExprCore expr)  = case expr of-                                     Var _        -> "Var"-                                     Type _       -> "Type"-                                     Lit _        -> "Lit"-                                     App _ _      -> "App"-                                     Lam _ _      -> "Lam"-                                     Let _ _      -> "Let"-                                     Case _ _ _ _ -> "Case"-                                     Cast _ _     -> "Cast"-                                     Tick _ _     -> "Tick"-                                     Coercion _   -> "Coercion"--typeConstructor :: Type -> String-typeConstructor = \case-                     TyVarTy{}    -> "TyVarTy"-                     AppTy{}      -> "AppTy"-                     TyConApp{}   -> "TyConApp"-                     FunTy{}      -> "FunTy"-                     ForAllTy{}   -> "ForAllTy"-                     LitTy{}      -> "LitTy"--coercionConstructor :: Coercion -> String-coercionConstructor = \case-                         Refl{}        -> "Refl"-                         TyConAppCo{}  -> "TyConAppCo"-                         AppCo{}       -> "AppCo"-                         ForAllCo{}    -> "ForAllCo"-                         CoVarCo{}     -> "CoVarCo"-                         AxiomInstCo{} -> "AxiomInstCo"-                         UnsafeCo{}    -> "UnsafeCo"-                         SymCo{}       -> "SymCo"-                         TransCo{}     -> "TransCo"-                         NthCo{}       -> "NthCo"-                         InstCo{}      -> "InstCo"-#if __GLASGOW_HASKELL__ > 706-                         LRCo{}        -> "LRCo"-#endif------------------------------------------------------------------------------ | Output a list of all free variables in an expression.-freeIdsQuery :: Monad m => Translate c m CoreExpr String-freeIdsQuery = do frees <- freeIdsT-                  return $ "Free identifiers are: " ++ showVars (toList frees)---- | Show a human-readable version of a list of 'Var's.-showVars :: [Var] -> String-showVars = show . map var2String---- | Lifted version of 'coreExprFreeIds'.-freeIdsT :: Monad m => Translate c m CoreExpr (Set Id)-freeIdsT = arr coreExprFreeIds---- | Lifted version of 'coreExprFreeVars'.-freeVarsT :: Monad m => Translate c m CoreExpr (Set Var)-freeVarsT = arr coreExprFreeVars---- | Lifted version of 'typeFreeVars'.-freeTyVarsT :: Monad m => Translate c m Type (Set Var)-freeTyVarsT = arr typeFreeVars---- | List all free variables in a type.-typeFreeVars :: Type -> Set Var-typeFreeVars = fromList . uniqSetToList . tyVarsOfType---- | List all free variables (including types) in the expression.-coreExprFreeVars :: CoreExpr -> Set Var-coreExprFreeVars  = fromList . uniqSetToList . exprFreeVars---- | List all free identifiers (value-level free variables) in the expression.-coreExprFreeIds :: CoreExpr -> Set Id-coreExprFreeIds  = fromList . uniqSetToList . exprFreeIds---- | The free variables in a case alternative, which excludes any identifiers bound in the alternative.-altFreeVarsT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreAlt (Set Var)-altFreeVarsT = altT mempty (\ _ -> idR) freeVarsT (\ () vs fvs -> fvs \\ fromList vs)---- | A variant of 'altFreeVarsT' that returns a function that accepts the case wild-card binder before giving a result.---   This is so we can use this with congruence combinators, for example:------   caseT id (const altFreeVarsT) $ \ _ wild _ fvs -> [ f wild | f <- fvs ]-altFreeVarsExclWildT :: (ExtendPath c Crumb, AddBindings c, Monad m) => Translate c m CoreAlt (Id -> Set Var)-altFreeVarsExclWildT = altT mempty (\ _ -> idR) freeVarsT (\ () vs fvs wild -> fvs \\ fromList (wild : vs))------------------------------------------------------------------------------ | [from GHC documentation] De-shadowing the program is sometimes a useful pre-pass.--- It can be done simply by running over the bindings with an empty substitution,--- becuase substitution returns a result that has no-shadowing guaranteed.------ (Actually, within a single /type/ there might still be shadowing, because--- 'substTy' is a no-op for the empty substitution, but that's probably OK.)-deShadowProgR :: Monad m => Rewrite c m CoreProg-deShadowProgR = arr (bindsToProg . deShadowBinds . progToBinds)---------------------------------------------------------------------------{--lookupRule :: (Activation -> Bool)	-- When rule is active-	    -> IdUnfoldingFun		-- When Id can be unfolded-            -> InScopeSet-	    -> Id -> [CoreExpr]-	    -> [CoreRule] -> Maybe (CoreRule, CoreExpr)--GHC HEAD:-type InScopeEnv = (InScopeSet, IdUnfoldingFun)--lookupRule :: DynFlags -> InScopeEnv-           -> (Activation -> Bool)      -- When rule is active-           -> Id -> [CoreExpr]-           -> [CoreRule] -> Maybe (CoreRule, CoreExpr)--}---- Neil: Commented this out as its not (currently) used.--- rulesToEnv :: [CoreRule] -> Map.Map String (Rewrite c m CoreExpr)--- rulesToEnv rs = Map.fromList---         [ ( unpackFS (ruleName r), rulesToRewrite c m [r] )---         | r <- rs---         ]--#if __GLASGOW_HASKELL__ > 706-rulesToRewriteH :: (ReadBindings c, HasDynFlags m, Monad m) => [CoreRule] -> Rewrite c m CoreExpr-#else-rulesToRewriteH :: (ReadBindings c, Monad m) => [CoreRule] -> Rewrite c m CoreExpr-#endif-rulesToRewriteH rs = translate $ \ c e -> do-    -- First, we normalize the lhs, so we can match it-    (Var fn,args) <- return $ collectArgs e-    -- Question: does this include Id's, or Var's (which include type names)-    -- Assumption: Var's.-    let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- toList (coreExprFreeVars e) ])-        -- The rough_args are just an attempt to try eliminate silly things-        -- that will never match-        _rough_args = map (const Nothing) args   -- rough_args are never used!!! FIX ME!-    -- Finally, we try match the rules-    -- trace (showSDoc (ppr fn GhcPlugins.<+> ppr args $$ ppr rs)) $-#if __GLASGOW_HASKELL__ > 706-    dflags <- getDynFlags-    case lookupRule dflags (in_scope, const NoUnfolding) (const True) fn args [r | r <- rs, ru_fn r == idName fn] of-#else-    case lookupRule (const True) (const NoUnfolding) in_scope fn args [r | r <- rs, ru_fn r == idName fn] of-#endif-        Nothing         -> fail "rule not matched"-        Just (r, expr)  -> do-            let e' = mkApps expr (drop (ruleArity r) args)-            ifM (liftM (and . map (inScope c) . toList) $ apply freeVarsT c e')-                (return e')-                (fail $ unlines ["Resulting expression after rule application contains variables that are not in scope."-                                ,"This can probably be solved by running the flatten-module command at the top level."])---- | Determine whether an identifier is in scope.-inScope :: ReadBindings c => c -> Id -> Bool-inScope c v = (v `boundIn` c) ||                 -- defined in this module-              case unfoldingInfo (idInfo v) of-                CoreUnfolding {} -> True         -- defined elsewhere-                DFunUnfolding {} -> True-                _                -> False---- | Lookup a rule and attempt to construct a corresponding rewrite.-rule :: (ReadBindings c, HasCoreRules c) => String -> Rewrite c HermitM CoreExpr-rule r = do-    theRules <- getHermitRules-    case lookup r theRules of-        Nothing -> fail $ "failed to find rule: " ++ show r-        Just rr -> rulesToRewriteH rr--rules :: (ReadBindings c, HasCoreRules c) => [String] -> Rewrite c HermitM CoreExpr-rules = orR . map rule--getHermitRules :: HasCoreRules c => Translate c HermitM a [(String, [CoreRule])]-getHermitRules = contextonlyT $ \ c -> do-    rb     <- liftCoreM getRuleBase-    hscEnv <- liftCoreM getHscEnv-    rb'    <- liftM eps_rule_base $ liftIO $ runIOEnv () $ readMutVar (hsc_EPS hscEnv)-    return [ ( unpackFS (ruleName r), [r] )-           | r <- hermitCoreRules c ++ concat (nameEnvElts rb) ++ concat (nameEnvElts rb')-           ]--rules_help :: HasCoreRules c => Translate c HermitM Core String-rules_help = do-    rulesEnv <- getHermitRules-    dynFlags <- constT getDynFlags-    return  $ (show (map fst rulesEnv) ++ "\n") ++-              showSDoc dynFlags (pprRulesForUser $ concatMap snd rulesEnv)--makeRule :: String -> Id -> CoreExpr -> CoreRule-makeRule rule_name nm =   mkRule True   -- auto-generated-                                 False  -- local-                                 (mkFastString rule_name)-                                 NeverActive    -- because we need to call for these-                                 (varName nm)-                                 []-                                 []---- TODO: check if a top-level binding-addCoreBindAsRule :: Monad m => String -> TH.Name -> Rewrite c m ModGuts-addCoreBindAsRule rule_name nm = contextfreeT $ \ modGuts ->-        case [ (v,e)-             | top_bnds <- mg_binds modGuts-             , (v,e) <- case top_bnds of-                            Rec bnds -> bnds-                            NonRec b e -> [(b,e)]-             ,  nm `cmpTHName2Var` v-             ] of-         [] -> fail $ "cannot find binding " ++ show nm-         [(v,e)] -> return $ modGuts { mg_rules = mg_rules modGuts-                                              ++ [makeRule rule_name v e]-                                     }-         _ -> fail $ "found multiple bindings for " ++ show nm---------------------------------------------------------------------------- | Performs dependency anlaysis on an expression.---   This can be useful to simplify a non-recursive recursive binding group to a non-recursive binding group.-occurAnalyseExpr :: CoreExpr -> CoreExpr-occurAnalyseExpr = OccurAnal.occurAnalyseExpr---- | Lifted version of 'occurAnalyseExpr'-occurAnalyseExprR :: Monad m => Rewrite c m CoreExpr-occurAnalyseExprR = arr occurAnalyseExpr-----{- Does not work (no export)--- Here is a hook into the occur analysis, and a way of looking at the result-occAnalysis ::  CoreExpr -> UsageDetails-occAnalysis = fst . occAnal (initOccEnv all_active_rules)--lookupUsageDetails :: UsageDetails -> Var -> Maybe OccInfo-lookupUsageDetails = lookupVarEnv---}---exprEqual :: CoreExpr -> CoreExpr -> Bool-exprEqual e1 e2 = eqExpr (mkInScopeSet $ exprsFreeVars [e1, e2]) e1 e2--exprsEqual :: [CoreExpr] -> Bool-exprsEqual = equivalent exprEqual---- Drew: surely this exists generally somewhere?--- for instance:---      equivalent ((==) `on` length) :: [[a]] -> Bool--- checks if all lists have the same length-equivalent :: (a -> a -> Bool) -> [a] -> Bool-equivalent _  []     = True-equivalent eq (x:xs) = all (eq x) xs---- The ideas for this function are directly extracted from--- the GHC function, CoreUtils.eqExprX-bindEqual :: CoreBind -> CoreBind -> Maybe Bool-bindEqual  (Rec ps1) (Rec ps2) = Just $ all2 (eqExprX id_unf env') rs1 rs2-      where-        id_unf _ = noUnfolding      -- Don't expand-        (bs1,rs1) = unzip ps1-        (bs2,rs2) = unzip ps2-        env = mkInScopeSet $ exprsFreeVars (rs1 ++ rs2) -- emptyInScopeSet-        env' = rnBndrs2 (mkRnEnv2 env) bs1 bs2--bindEqual  (NonRec _ e1) (NonRec _ e2) = Just $ exprEqual e1 e2--bindEqual _ _ = Nothing------------------------------------------------------------coreEqual :: Core -> Core -> Maybe Bool-coreEqual (ExprCore e1) (ExprCore e2) = Just $ e1 `exprEqual` e2-coreEqual (BindCore b1) (BindCore b2) = b1 `bindEqual` b2-coreEqual (DefCore dc1) (DefCore dc2) = defsToRecBind [dc1] `bindEqual` defsToRecBind [dc2]-coreEqual _             _             = Nothing--compareValues :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> TH.Name -> Translate c m Core ()-compareValues n1 n2 = do-        p1 <- onePathToT (namedBinding n1)-        p2 <- onePathToT (namedBinding n2)-        e1 <- pathT p1 idR-        e2 <- pathT p2 idR-        case e1 `coreEqual` e2 of-          Nothing    -> fail $ show n1 ++ " and " ++ show n2 ++ " are incomparable."-          Just False -> fail $ show n1 ++ " and " ++ show n2 ++ " are not equal."-          Just True  -> return ()-------------------------------------------------------------- | Try to figure out the arity of an identifier.-arityOf :: ReadBindings c => c -> Id -> Int-arityOf env i =-     case lookupHermitBinding i env of-        Nothing       -> idArity i-        -- Note: the exprArity will call idArity if-        -- it hits an id; perhaps we should do the counting-        -- The advantage of idArity is it will terminate, though.-        Just b -> case hermitBindingExpr b of-                    Just e  -> exprArity e-                    Nothing -> 0 -- TODO: Why do we return 0 here?------------------------------------------------- | Run the Core Lint typechecker.--- Fails on errors, with error messages.--- Succeeds returning warnings.-lintModuleT :: TranslateH ModGuts String-lintModuleT = arr (bindsToProg . mg_binds) >>> lintProgramT--lintProgramT :: TranslateH CoreProg String-lintProgramT = do-    bnds <- arr progToBinds-    dflags <- constT getDynFlags-    let (warns, errs) = CoreLint.lintCoreBindings bnds-        dumpSDocs endMsg = Bag.foldBag (\d r -> d ++ ('\n':r)) (showSDoc dflags) endMsg-    if Bag.isEmptyBag errs-        then return $ dumpSDocs "Core Lint Passed" warns-        else observeR (dumpSDocs "" errs) >>> fail "Core Lint Failed"---- | Note: this can miss several things that a whole-module core lint will find.--- For instance, running this on the RHS of a binding, the type of the RHS will--- not be checked against the type of the binding. Running on the whole let expression--- will catch that however.-lintExprT :: (BoundVars c, Monad m, HasDynFlags m) => Translate c m CoreExpr String-lintExprT = translate $ \ c e -> do-    dflags <- getDynFlags-    maybe (return "Core Lint Passed") (fail . showSDoc dflags)-                 $ CoreLint.lintUnfolding noSrcLoc (toList $ boundVars c) e--specConstrR :: RewriteH ModGuts-specConstrR = do-    rs  <- extractT specRules-    e'  <- contextfreeT $ liftCoreM . SpecConstr.specConstrProgram-    rs' <- return e' >>> extractT specRules-    let specRs = deleteFirstsBy ((==) `on` ru_name) rs' rs-    return e' >>> extractR (repeatR (anyCallR (promoteExprR $ rulesToRewriteH specRs)))---- | Get all the specialization rules on a binding.---   These are created by SpecConstr and other GHC passes.-idSpecRules :: TranslateH Id [CoreRule]-idSpecRules = contextfreeT $ \ i -> let SpecInfo rs _ = specInfo (idInfo i) in return rs---- | Promote 'idSpecRules' to CoreBind.-bindSpecRules :: TranslateH CoreBind [CoreRule]-bindSpecRules =    recT (\_ -> defT idSpecRules (return ()) const) concat-                <+ nonRecT idSpecRules (return ()) const---- | Find all specialization rules in a Core fragment.-specRules :: TranslateH Core [CoreRule]-specRules = crushtdT $ promoteBindT bindSpecRules---- | Top-down traversal tuned to matching function calls.-anyCallR :: forall c m. (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m)-         => Rewrite c m Core -> Rewrite c m Core-anyCallR rr = prefixFailMsg "any-call failed: " $-              readerT $ \ e -> case e of-        ExprCore (App {}) -> childR App_Arg rec >+> (rr <+ childR App_Fun rec)-        ExprCore (Var {}) -> rr-        _                 -> anyR rec-    where rec :: Rewrite c m Core-          rec = anyCallR rr
− src/Language/HERMIT/Primitive/Inline.hs
@@ -1,188 +0,0 @@-{-# LANGUAGE CPP, TupleSections, FlexibleContexts #-}-module Language.HERMIT.Primitive.Inline-         ( -- * Inlining-           externals-         , getUnfolding-         , inline-         , inlineName-         , inlineScrutinee-         , inlineCaseBinder-         , inlineTargets-         )--where--import GhcPlugins-#if __GLASGOW_HASKELL__ > 706-#else-import TcType (tcSplitDFunTy)-#endif--import Control.Arrow--import Data.Set (member)--import Language.HERMIT.Context-import Language.HERMIT.Core-import Language.HERMIT.External-import Language.HERMIT.GHC-import Language.HERMIT.Kure-import Language.HERMIT.Monad--import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.GHC hiding (externals)--import qualified Language.Haskell.TH as TH-import Language.Haskell.TH.Syntax (showName)------------------------------------------------------------------------------ | 'External's for inlining variables.-externals :: [External]-externals =-            [ external "inline" (promoteExprR inline :: RewriteH Core)-                [ "(Var n) ==> <defn of n>, fails otherwise" ].+ Eval .+ Deep .+ TODO-            , external "inline-scrutinee" (promoteExprR inlineScrutinee :: RewriteH Core)-                [ "(Var n) ==> <defn of n>, fails otherwise"-                , "In the case of case binders, replaces with scrutinee expression, "-                , "rather than constructor or literal." ].+ Eval .+ Deep .+ TODO-            , external "inline" (promoteExprR . inlineName :: TH.Name -> RewriteH Core)-                [ "Restrict inlining to a given name" ].+ Eval .+ Deep .+ TODO-            , external "inline-case-binder" (promoteExprR inlineCaseBinder :: RewriteH Core)-                [ "Inline if this variable is a case binder." ].+ Eval .+ Deep {- this causes a Dead Id core list error if in bash .+ Bash -} .+ TODO-            ]------------------------------------------------------------------------------ | If the current variable matches the given name, then inline it.-inlineName :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM CoreExpr-inlineName nm = prefixFailMsg ("inline '" ++ showName nm ++ " failed: ") $-                withPatFailMsg (wrongExprForm "Var v") $-   do Var v <- idR-      guardMsg (cmpTHName2Var nm v) $ " does not match " ++ var2String v ++ "."-      inline---- | Inline the current variable.-inline :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-inline = configurableInline False False---- | Inline the current variable, using the scrutinee rather than the case alternative if it is a case wild-card binder.-inlineScrutinee :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-inlineScrutinee = configurableInline True False---- | If the current variable is a case wild-card binder, then inline it.-inlineCaseBinder :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-inlineCaseBinder = configurableInline False True---- | The implementation of inline, an important transformation.--- This *only* works on a Var of the given name. It can trivially--- be prompted to more general cases.-configurableInline :: (ExtendPath c Crumb, AddBindings c, ReadBindings c)-                   => Bool -- ^ Inline the scrutinee instead of the patten match (for case binders).-                   -> Bool -- ^ Only inline if this variable is a case binder.-                   -> Rewrite c HermitM CoreExpr-configurableInline scrutinee caseBinderOnly =-   prefixFailMsg "Inline failed: " $-   withPatFailMsg (wrongExprForm "Var v") $-   do (c, Var v) <- exposeT-      (e,d) <- constT $ getUnfolding scrutinee caseBinderOnly v c-      return e >>> (setFailMsg "values in inlined expression have been rebound." $-                    accepterR (extractT $ ensureDepth d))----- | Ensure all the free variables in an expression were bound above a given depth.--- Assumes minimum depth is 0.-ensureDepth :: (ExtendPath c Crumb, AddBindings c, ReadBindings c, MonadCatch m) => Int -> Translate c m Core Bool-ensureDepth d = do-    frees <- promoteT freeVarsT-    ds <- collectT $ promoteExprT $ varT $ translate $ \ c i -> return $ if i `member` frees-                                                                          then maybe (i,0) (\ b -> (i, fst b)) (lookupHermitBinding i c)-                                                                          else (i,0)-    return $ all (toSnd (<= d)) ds--getUnfolding :: ReadBindings c-             => Bool -- ^ Get the scrutinee instead of the patten match (for case binders).-             -> Bool -- ^ Only succeed if this variable is a case binder.-             -> Id -> c -> HermitM (CoreExpr, Int)-getUnfolding scrutinee caseBinderOnly i c =-    case lookupHermitBinding i c of-        Nothing -> if caseBinderOnly-                   then fail "not a case binder"-                   else case unfoldingInfo (idInfo i) of-                            CoreUnfolding { uf_tmpl = uft } -> return (uft, 0)-#if __GLASGOW_HASKELL__ > 706-                            dunf@(DFunUnfolding {})         -> dFunExpr dunf >>= return . (,0)-#else-                            DFunUnfolding _arity dc args    -> dFunExpr dc args (idType i) >>= return . (,0)-#endif-                            _                               -> fail $ "cannot find unfolding in Env or IdInfo."-        Just (depth,b) -> case b of-                            CASEWILD s alt -> return $ if scrutinee-                                                        then (s, depth)-                                                        else let tys = tyConAppArgs (idType i)-                                                              in either (,depth) (,depth+1) (alt2Exp s tys alt)-                            _              -> if caseBinderOnly-                                               then fail "not a case binder."-                                               else case hermitBindingSiteExpr b of-                                                      Just e  -> return (e, depth)-                                                      Nothing -> fail $ "variable is not bound to an expression."---- | Convert lhs of case alternative to a constructor application expression,---   or a default expression in the case of the DEFAULT alternative.---   Accepts a list of types to apply to the constructor before the value args.------ > data T a b = C a b Int------ Pseudocode:------ > alt2Exp (...) [a,b] (C, [x,y,z]) ==> C a b (x::a) (y::b) (z::Int)------ The 'Either' denotes whether we picked the default (scrutinee) or built an expression.--- This matters for the depth check.-alt2Exp :: CoreExpr -> [Type] -> (AltCon,[Id]) -> Either CoreExpr CoreExpr-alt2Exp d _   (DEFAULT   , _ ) = Left d-alt2Exp _ _   (LitAlt l  , _ ) = Right $ Lit l-alt2Exp _ tys (DataAlt dc, as) = Right $ mkCoreConApps dc (map Type tys ++ map varToCoreExpr as)---- | Get list of possible inline targets. Used by shell for completion.-inlineTargets :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Translate c HermitM Core [String]-inlineTargets = collectT $ promoteT $ whenM (testM inline) (varT $ arr var2String)---- | Build a CoreExpr for a DFunUnfolding-#if __GLASGOW_HASKELL__ > 706-{--data Unfolding-  = ...-  | DFunUnfolding {     -- The Unfolding of a DFunId-                -- See Note [DFun unfoldings]-                --     df = /\a1..am. \d1..dn. MkD t1 .. tk-                        --                                 (op1 a1..am d1..dn)-                    --                                 (op2 a1..am d1..dn)-        df_bndrs :: [Var],      -- The bound variables [a1..m],[d1..dn]-        df_con   :: DataCon,    -- The dictionary data constructor (never a newtype datacon)-        df_args  :: [CoreExpr]  -- Args of the data con: types, superclasses and methods,-    }                           -- in positional order--}-dFunExpr :: Unfolding -> HermitM CoreExpr--- TODO: is this correct?-dFunExpr dunf@(DFunUnfolding {}) = return $ trace "dFunExpr" $ mkCoreConApps (df_con dunf) (df_args dunf)-dFunExpr _ = fail "dFunExpr: not a DFunUnfolding"-#else-dFunExpr :: DataCon -> [DFunArg CoreExpr] -> Type -> HermitM CoreExpr-dFunExpr dc args ty = do-    let (_, _, _, tcArgs) = tcSplitDFunTy ty-        (forallTvs, ty')  = splitForAllTys ty-        (argTys, _resTy)  = splitFunTys ty'--    ids <- mapM (uncurry newIdH) $ zip [ [ch] | ch <- cycle ['a'..'z'] ] argTys-    vars <- mapM (cloneVarH id) forallTvs--    let allVars = varsToCoreExprs $ vars ++ ids--        mkArg (DFunLamArg i) = allVars !! i-        mkArg (DFunPolyArg e) = mkCoreApps e allVars--    return $ mkCoreConApps dc $ map Type tcArgs ++ map mkArg args-#endif--------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Kure.hs
@@ -1,101 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}--module Language.HERMIT.Primitive.Kure-       ( -- * KURE Strategies-         -- This list contains reflections of the KURE strategies as 'External's.-         externals-       )-where--import Control.Arrow--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.External----------------------------------------------------------------------------------------externals :: [External]-externals = map (.+ KURE)-   [ external "id"         (idR :: RewriteH Core)-       [ "perform the identity"] .+ Shallow-   , external "fail"       (fail :: String -> RewriteH Core)-       [ "a failing rewrite"]-   , external "<+"         ((<+) :: RewriteH Core -> RewriteH Core -> RewriteH Core)-       [ "perform the first rewrite, and then, if it fails, perform the second rewrite" ]-   , external "<+"         ((<+) :: TranslateH Core () -> TranslateH Core () -> TranslateH Core ())-       [ "perform the first check, and then, if it fails, perform the second check" ]-   , external ">>>"        ((>>>) :: RewriteH Core -> RewriteH Core -> RewriteH Core)-       [ "compose rewrites, requiring both to succeed" ]-   , external ">>>"        ((>>>) :: BiRewriteH Core -> BiRewriteH Core -> BiRewriteH Core)-       [ "compose bidirectional rewrites, requiring both to succeed" ]-   , external ">+>"        ((>+>) :: RewriteH Core -> RewriteH Core -> RewriteH Core)-       [ "compose rewrites, allowing one to fail" ]-   , external "try"        (tryR :: RewriteH Core -> RewriteH Core)-       [ "tries a rewrite, and performs an identity if this rewrite fails" ]-   , external "repeat"     (repeatR :: RewriteH Core -> RewriteH Core)-       [ "repeats a rewrite until it would fail" ] .+ Loop-   , external "replicate"  ((\ n -> andR . replicate n)  :: Int -> RewriteH Core -> RewriteH Core)-       [ "repeats a rewrite n times" ]-   , external "all"        (allR :: RewriteH Core -> RewriteH Core)-       [ "apply a rewrite to all children of the node, requiring success at every child" ] .+ Shallow-   , external "any"        (anyR :: RewriteH Core -> RewriteH Core)-       [ "apply a rewrite to all children of the node, requiring success for at least one child" ] .+ Shallow-   , external "one"        (oneR :: RewriteH Core -> RewriteH Core)-       [ "apply a rewrite to the first child of the node for which it can succeed" ] .+ Shallow-   , external "all-bu"     (allbuR :: RewriteH Core -> RewriteH Core)-       [ "promotes a rewrite to operate over an entire tree in bottom-up order, requiring success at each node" ] .+ Deep-   , external "all-td"     (alltdR :: RewriteH Core -> RewriteH Core)-       [ "promotes a rewrite to operate over an entire tree in top-down order, requiring success at every node" ] .+ Deep-   , external "all-du"     (allduR :: RewriteH Core -> RewriteH Core)-       [ "apply a rewrite twice, in a top-down and bottom-up way, using one single tree traversal",-         "succeeding if they all succeed"] .+ Deep-   , external "any-bu"     (anybuR :: RewriteH Core -> RewriteH Core)-       [ "promotes a rewrite to operate over an entire tree in bottom-up order, requiring success for at least one node" ] .+ Deep-   , external "any-td"     (anytdR :: RewriteH Core -> RewriteH Core)-       [ "promotes a rewrite to operate over an entire tree in top-down order, requiring success for at least one node" ] .+ Deep-   , external "any-du"     (anyduR :: RewriteH Core -> RewriteH Core)-       [ "apply a rewrite twice, in a top-down and bottom-up way, using one single tree traversal",-         "succeeding if any succeed"] .+ Deep-   , external "one-td"     (onetdR :: RewriteH Core -> RewriteH Core)-       [ "applies a rewrite to the first node (in a top-down order) for which it can succeed" ] .+ Deep-   , external "one-bu"     (onebuR :: RewriteH Core -> RewriteH Core)-       [ "applies a rewrite to the first node (in a bottom-up order) for which it can succeed" ] .+ Deep-   , external "prune-td"   (prunetdR :: RewriteH Core -> RewriteH Core)-       [ "attempt to apply a rewrite in a top-down manner, prunning at successful rewrites" ] .+ Deep-   , external "innermost"  (innermostR :: RewriteH Core -> RewriteH Core)-       [ "a fixed-point traveral, starting with the innermost term" ] .+ Deep .+ Loop-   , external "focus"      (hfocusR :: TranslateH Core PathH -> RewriteH Core -> RewriteH Core)-       [ "apply a rewrite to a focal point"] .+ Navigation .+ Deep-   , external "focus"      (hfocusT :: TranslateH Core PathH -> TranslateH Core String -> TranslateH Core String)-       [ "apply a query at a focal point"] .+ Navigation .+ Deep-   , external "focus"      (hfocusR . return :: PathH -> RewriteH Core -> RewriteH Core)-       [ "apply a rewrite to a focal point"] .+ Navigation .+ Deep-   , external "focus"      (hfocusT . return :: PathH -> TranslateH Core String -> TranslateH Core String)-       [ "apply a query at a focal point"] .+ Navigation .+ Deep-   , external "when"       ((>>) :: TranslateH Core () -> RewriteH Core -> RewriteH Core)-       [ "apply a rewrite only if the check succeeds" ] .+ Predicate-   , external "not"        (notM :: TranslateH Core () -> TranslateH Core ())-       [ "cause a failing check to succeed, a succeeding check to fail" ] .+ Predicate-   , external "invert"     (invertBiT :: BiRewriteH Core -> BiRewriteH Core)-       [ "reverse a bidirectional rewrite" ]-   , external "foreward"   (forewardT :: BiRewriteH Core -> RewriteH Core)-       [ "apply a bidirectional rewrite forewards" ]-   , external "backward"   (backwardT :: BiRewriteH Core -> RewriteH Core)-       [ "apply a bidirectional rewrite backwards" ]-   ]----------------------------------------------------------------------------------------hfocusR :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Core PathH -> Rewrite c m Core -> Rewrite c m Core-hfocusR tp r = do p <- tp-                  pathR p r-{-# INLINE hfocusR #-}--hfocusT :: (ExtendPath c Crumb, ReadPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Core PathH -> Translate c m Core String -> Translate c m Core String-hfocusT tp t = do p <- tp-                  pathT p t-{-# INLINE hfocusT #-}--------------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Local.hs
@@ -1,215 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}--module Language.HERMIT.Primitive.Local-       ( -- * Local Structural Manipulations-         Language.HERMIT.Primitive.Local.externals-         -- ** Case Expressions-       , module Language.HERMIT.Primitive.Local.Case-         -- ** Cast Expressions-       , module Language.HERMIT.Primitive.Local.Cast-         -- ** Let Expressions-       , module Language.HERMIT.Primitive.Local.Let-         -- ** Miscellaneous-       , abstract-       , nonrecToRec-       , betaReduce-       , betaReducePlus-       , betaExpand-       , etaReduce-       , etaExpand-       , multiEtaExpand-       , flattenModule-       , flattenProgramR-       , flattenProgramT-       )-where--import GhcPlugins--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.Monad-import Language.HERMIT.External-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.GHC-import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.Local.Case hiding (externals)-import qualified Language.HERMIT.Primitive.Local.Case as Case-import Language.HERMIT.Primitive.Local.Cast hiding (externals)-import qualified Language.HERMIT.Primitive.Local.Cast as Cast-import Language.HERMIT.Primitive.Local.Let hiding (externals)-import qualified Language.HERMIT.Primitive.Local.Let as Let--import qualified Language.Haskell.TH as TH--import Control.Arrow--import Data.Set (notMember)------------------------------------------------------------------------------------ | Externals for local structural manipulations.---   (Many taken from Chapter 3 of Andre Santos' dissertation.)-externals :: [External]-externals =-    [ external "nonrec-to-rec" (promoteBindR nonrecToRec :: RewriteH Core)-        [ "convert a non-recursive binding into a recursive binding group with a single definition."-        , "NonRec v e ==> Rec [Def v e]" ]-    , external "beta-reduce" (promoteExprR betaReduce :: RewriteH Core)-        [ "((\\ v -> E1) E2) ==> let v = E2 in E1"-        , "this form of beta-reduction is safe if E2 is an arbitrary"-        , "expression (won't duplicate work)" ]                                 .+ Eval .+ Shallow-    , external "beta-reduce-plus" (promoteExprR betaReducePlus :: RewriteH Core)-        [ "perform one or more beta-reductions."]                               .+ Eval .+ Shallow .+ Bash-    , external "beta-expand" (promoteExprR betaExpand :: RewriteH Core)-        [ "(let v = e1 in e2) ==> (\\ v -> e2) e1" ]                            .+ Shallow-    , external "eta-reduce" (promoteExprR etaReduce :: RewriteH Core)-        [ "(\\ v -> e1 v) ==> e1" ]                                             .+ Eval .+ Shallow .+ Bash-    , external "eta-expand" (promoteExprR . etaExpand . show :: TH.Name -> RewriteH Core)-        [ "\"eta-expand 'v\" performs e1 ==> (\\ v -> e1 v)" ]                  .+ Shallow .+ Introduce-    , external "flatten-module" (promoteModGutsR flattenModule :: RewriteH Core)-        [ "Flatten all the top-level binding groups in the module to a single recursive binding group."-        , "This can be useful if you intend to appply GHC RULES." ]-    , external "flatten-program" (promoteProgR flattenProgramR :: RewriteH Core)-        [ "Flatten all the top-level binding groups in a program (list of binding groups) to a single recursive binding group."-        , "This can be useful if you intend to apply GHC RULES." ]-    , external "abstract" (promoteExprR . abstract :: TH.Name -> RewriteH Core)-        [ "Abstract over a variable using a lambda."-        , "e  ==>  (\\ x -> e) x" ]                                             .+ Shallow .+ Introduce .+ Context-    ]-    ++ Case.externals-    ++ Cast.externals-    ++ Let.externals------------------------------------------------------------------------------------ | NonRec v e ==> Rec [Def v e]-nonrecToRec :: MonadCatch m => Rewrite c m CoreBind-nonrecToRec = prefixFailMsg "Converting non-recursive binding to recursive binding failed: " $-              setFailMsg (wrongExprForm "NonRec v e") $-  do NonRec v e <- idR-     guardMsg (isId v) "type variables cannot be defined recursively."-     return $ Rec [(v,e)]------------------------------------------------------------------------------------ | ((\\ v -> e1) e2) ==> (let v = e2 in e1)---   This form of beta-reduction is safe if e2 is an arbitrary---   expression (won't duplicate work).-betaReduce :: MonadCatch m => Rewrite c m CoreExpr-betaReduce = setFailMsg ("Beta-reduction failed: " ++ wrongExprForm "App (Lam v e1) e2") $-    do App (Lam v e1) e2 <- idR-       return $ Let (NonRec v e2) e1---multiBetaReduce :: MonadCatch m =>  (Int -> Bool) -> Rewrite c m CoreExpr-multiBetaReduce p = prefixFailMsg "Multi-Beta-Reduce failed: " $-    do-        e <- idR-        let (f,xs) = collectArgs e-        guardMsg (p (length xs)) "incorrect number of arguments."--        let (vs,e0) = collectBinders f--        guardMsg (length vs >= length xs) "insufficent lambdas."--        let (vs1,vs2) = splitAt (length xs) vs--        return-           $ mkLets (zipWith NonRec vs1 xs)-           $ mkLams vs2 e0---- TODO: inline this everywhere--- Neil: Are we sure we want to inline this?--- | Perform one or more beta-reductions.-betaReducePlus :: MonadCatch m => Rewrite c m CoreExpr-betaReducePlus = multiBetaReduce (> 0)--{---        tagFailR "betaReducePlus failed." $-        appT liftLambda idR App >>> beta_reduce-  where-          -- lift lambda finds the (perhaps hidden) lambda, and brings it out-          liftLambda = observeR "pre-liftLambda" >>> liftLambda' >>> observeR "post-liftLambda"-          liftLambda' =-                   (do e@(Lam {}) <- idR-                       return e)-                <+ (betaReducePlus-                        >>> observeR "liftLambda(UP)"-                            -- let v = e in ...-                            -- TODO: check scope here-                        >>> (do Let bds (Lam v e) <- idR-                                return (Lam v (Let bds e)))-                   )--}---- | (let v = e1 in e2) ==> (\\ v -> e2) e1-betaExpand :: MonadCatch m => Rewrite c m CoreExpr-betaExpand = setFailMsg ("Beta-expansion failed: " ++ wrongExprForm "Let (NonRec v e1) e2") $-    do Let (NonRec v e1) e2 <- idR-       return $ App (Lam v e2) e1------------------------------------------------------------------------------------ | (\\ v -> e1 v) ==> e1-etaReduce :: MonadCatch m => Rewrite c m CoreExpr-etaReduce = prefixFailMsg "Eta-reduction failed: " $-            withPatFailMsg (wrongExprForm "Lam v1 (App f e)") $-            do Lam v1 (App f e) <- idR-               case e of-                  Var v2  -> guardMsg (v1 == v2) "the expression has the right form, but the variables are not equal."-                  Type ty -> case getTyVar_maybe ty of-                               Nothing -> fail "the argument expression is not a type variable."-                               Just v2 -> guardMsg (v1 == v2) "type variables are not equal."-                  _       -> fail "the argument expression is not a variable."-               guardMsg (v1 `notMember` coreExprFreeIds f) $ var2String v1 ++ " is free in the function being applied."-               return f---- | e1 ==> (\\ v -> e1 v)-etaExpand :: String -> Rewrite c HermitM CoreExpr-etaExpand nm = prefixFailMsg "Eta-expansion failed: " $-               contextfreeT $ \ e -> let ty = exprType e in-        case splitFunTy_maybe ty of-          Just (argTy, _) -> do v <- newIdH nm argTy-                                return $ Lam v (App e (varToCoreExpr v))-          Nothing         -> case splitForAllTy_maybe ty of-                               Just (tv,_) -> do v <- newTyVarH nm (tyVarKind tv)-                                                 return $ Lam v (App e (varToCoreExpr v))-                               Nothing -> fail "type of expression is not a function or a forall."---- | Perform multiple eta-expansions.-multiEtaExpand :: (ExtendPath c Crumb, AddBindings c) => [String] -> Rewrite c HermitM CoreExpr-multiEtaExpand []       = idR-multiEtaExpand (nm:nms) = etaExpand nm >>> lamAllR idR (multiEtaExpand nms)------------------------------------------------------------------------------------ | Flatten all the top-level binding groups in the module to a single recursive binding group.-flattenModule :: (ExtendPath c Crumb, Monad m) => Rewrite c m ModGuts-flattenModule = modGutsR flattenProgramR---- | Flatten all the top-level binding groups in a program to a program containing a single recursive binding group.-flattenProgramR :: Monad m => Rewrite c m CoreProg-flattenProgramR = do bnd <- flattenProgramT-                     return (bindsToProg [bnd])---- | Flatten all the top-level binding groups in a program to a single recursive binding group.-flattenProgramT :: Monad m => Translate c m CoreProg CoreBind-flattenProgramT = do bds <- arr (concatMap bindToIdExprs . progToBinds)-                     guardMsg (nodups $ map fst bds) "Top-level bindings contain multiple occurrences of a name."-                     return (Rec bds)------------------------------------------------------------------------------------ | Abstract over a variable using a lambda.---   e  ==>  (\ x. e) x-abstract :: (ReadBindings c, MonadCatch m) => TH.Name -> Rewrite c m CoreExpr-abstract nm = prefixFailMsg "abstraction failed: " $-   do e <- idR-      v <- findBoundVarT nm-      return (App (Lam v e) (varToCoreExpr v))--------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Local/Case.hs
@@ -1,273 +0,0 @@-{-# LANGUAGE CPP, MultiWayIf, ScopedTypeVariables, FlexibleContexts #-}--module Language.HERMIT.Primitive.Local.Case-    ( -- * Rewrites on Case Expressions-      externals-    , caseElim-    , caseFloatApp-    , caseFloatArg-    , caseFloatCase-    , caseFloatCast-    , caseFloatLet-    , caseFloat-    , caseUnfloat-    , caseUnfloatApp-    , caseUnfloatArgs-    , caseReduce-    , caseReduceDatacon-    , caseReduceLiteral-    , caseSplit-    , caseSplitInline-    ) where--import GhcPlugins--import Data.List-import Data.Monoid-import Data.Set (intersection, fromList, toList, member, unions)-import qualified Data.Set as S-import Control.Arrow-import Control.Monad (liftM)--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.GHC-import Language.HERMIT.External--import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.GHC hiding (externals)-import Language.HERMIT.Primitive.Inline hiding (externals)-import Language.HERMIT.Primitive.AlphaConversion hiding (externals)--import qualified Language.Haskell.TH as TH---- NOTE: these are hard to test in small examples, as GHC does them for us, so use with caution----------------------------------------------------------------------------------- | Externals relating to Case expressions.-externals :: [External]-externals =-    [ external "case-elim" (promoteExprR caseElim :: RewriteH Core)-        [ "case s of w; C vs -> e ==> e if w and vs are not free in e" ]     .+ Shallow-    , external "case-float-app" (promoteExprR caseFloatApp :: RewriteH Core)-        [ "(case ec of alt -> e) v ==> case ec of alt -> e v" ]              .+ Commute .+ Shallow .+ Bash-    , external "case-float-arg" (promoteExprR caseFloatArg :: RewriteH Core)-        [ "f (case s of alt -> e) ==> case s of alt -> f e" ]                .+ Commute .+ Shallow .+ PreCondition-    , external "case-float-case" (promoteExprR caseFloatCase :: RewriteH Core)-        [ "case (case ec of alt1 -> e1) of alta -> ea ==> case ec of alt1 -> case e1 of alta -> ea" ] .+ Commute .+ Eval .+ Bash-    , external "case-float-cast" (promoteExprR caseFloatCast :: RewriteH Core)-        [ "cast (case s of p -> e) co ==> case s of p -> cast e co" ]        .+ Shallow .+ Commute .+ Bash-    , external "case-float-let" (promoteExprR caseFloatLet :: RewriteH Core)-        [ "let v = case ec of alt1 -> e1 in e ==> case ec of alt1 -> let v = e1 in e" ] .+ Commute .+ Shallow .+ Bash-    , external "case-float" (promoteExprR caseFloat :: RewriteH Core)-        [ "Float a Case whatever the context." ]                             .+ Commute .+ Shallow .+ PreCondition-    , external "case-unfloat" (promoteExprR caseUnfloat :: RewriteH Core)-        [ "Unfloat a Case whatever the context." ]                             .+ Commute .+ Shallow .+ PreCondition-    , external "case-unfloat-args" (promoteExprR caseUnfloatArgs :: RewriteH Core)-        [ "Unfloat a Case whose alternatives are parallel applications of the same function." ] .+ Commute .+ Shallow .+ PreCondition-    -- , external "case-unfloat-app" (promoteExprR caseUnfloatApp :: RewriteH Core)-    --     [ "Unfloat a Case whole alternatives are applications of different functions with the same arguments." ] .+ Commute .+ Shallow .+ PreCondition-    , external "case-reduce" (promoteExprR caseReduce :: RewriteH Core)-        [ "case-reduce-datacon <+ case-reduce-literal" ]                     .+ Shallow .+ Eval .+ Bash-    , external "case-reduce-datacon" (promoteExprR caseReduceDatacon :: RewriteH Core)-        [ "case-of-known-constructor"-        , "case C v1..vn of C w1..wn -> e ==> let { w1 = v1 ; .. ; wn = vn } in e" ]    .+ Shallow .+ Eval-    , external "case-reduce-literal" (promoteExprR caseReduceLiteral :: RewriteH Core)-        [ "case L of L -> e ==> e" ]                                         .+ Shallow .+ Eval-    , external "case-split" (promoteExprR . caseSplit :: TH.Name -> RewriteH Core)-        [ "case-split 'x"-        , "e ==> case x of C1 vs -> e; C2 vs -> e, where x is free in e" ]-    , external "case-split-inline" (caseSplitInline :: TH.Name -> RewriteH Core)-        [ "Like case-split, but additionally inlines the matched constructor "-        , "applications for all occurances of the named variable." ]-    ]------------------------------------------------------------------------------------ | case s of w; C vs -> e ==> e if w and vs are not free in e-caseElim :: Rewrite c HermitM CoreExpr-caseElim = prefixFailMsg "Case elimination failed: " $-           withPatFailMsg (wrongExprForm "Case s bnd ty alts") $ do-    Case _ bnd _ alts <- idR-    case alts of-        [(_, vs, e)] -> do fvs <- applyInContextT freeVarsT e-                           guardMsg (S.null $ intersection (fromList (bnd:vs)) fvs) "wildcard or pattern binders free in RHS."-                           return e-        _ -> fail "more than one case alternative."---- | (case s of alt1 -> e1; alt2 -> e2) v ==> case s of alt1 -> e1 v; alt2 -> e2 v-caseFloatApp :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseFloatApp = prefixFailMsg "Case floating from App function failed: " $-  do-    captures    <- appT (liftM (map fromList) caseAltVarsT) freeVarsT (flip (map . intersection))-    wildCapture <- appT caseWildIdT freeVarsT member-    appT ((if not wildCapture then idR else alphaCaseBinder Nothing)-          >>> caseAllR idR idR idR (\i -> if S.null (captures !! i) then idR else alphaAlt)-         )-          idR-          (\(Case s b _ty alts) v -> let newTy = exprType (App (case head alts of (_,_,f) -> f) v)-                                     in Case s b newTy $ mapAlts (flip App v) alts)---- | @f (case s of alt1 -> e1; alt2 -> e2)@ ==> @case s of alt1 -> f e1; alt2 -> f e2@---   Only safe if @f@ is strict.-caseFloatArg :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseFloatArg = prefixFailMsg "Case floating from App argument failed: " $-  do-    captures    <- appT freeVarsT (liftM (map fromList) caseAltVarsT) (map . intersection)-    wildCapture <- appT freeVarsT caseWildIdT (flip member)-    appT idR-         ((if not wildCapture then idR else alphaCaseBinder Nothing)-          >>> caseAllR idR idR idR (\i -> if S.null (captures !! i) then idR else alphaAlt)-         )-         (\f (Case s b _ty alts) -> let newTy = exprType (App f (case head alts of (_,_,e) -> e))-                                    in Case s b newTy $ mapAlts (App f) alts)---- | case (case s1 of alt11 -> e11; alt12 -> e12) of alt21 -> e21; alt22 -> e22---   ==>---   case s1 of---     alt11 -> case e11 of alt21 -> e21; alt22 -> e22---     alt12 -> case e12 of alt21 -> e21; alt22 -> e22-caseFloatCase :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseFloatCase = prefixFailMsg "Case floating from Case failed: " $-  do-    captures <- caseT (liftM (map fromList) caseAltVarsT) idR mempty (const altFreeVarsExclWildT) (\ vss bndr () fs -> map (intersection (unions $ map ($ bndr) fs)) vss)-    -- does the binder of the inner case, shadow a free variable in any of the outer case alts?-    -- notice, caseBinderVarT returns a singleton list-    wildCapture <- caseT caseWildIdT idR mempty (const altFreeVarsExclWildT) (\ innerBndr bndr () fvs -> innerBndr `member` unions (map ($ bndr) fvs))-    caseT ((if not wildCapture then idR else alphaCaseBinder Nothing)-           >>> caseAllR idR idR idR (\i -> if S.null (captures !! i) then idR else alphaAlt)-          )-          idR-          idR-          (const idR)-          (\ (Case s1 b1 _ alts1) b2 ty alts2 -> Case s1 b1 ty $ mapAlts (\s -> Case s b2 ty alts2) alts1)---- | let v = case s of alt1 -> e1 in e ==> case s of alt1 -> let v = e1 in e-caseFloatLet :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseFloatLet = prefixFailMsg "Case floating from Let failed: " $-  do vs <- letNonRecT idR caseAltVarsT mempty (\ letVar caseVars () -> letVar `elem` concat caseVars)-     let bdsAction = if not vs then idR else nonRecAllR idR alphaCase-     letT bdsAction idR $ \ (NonRec v (Case s b _ alts)) e -> Case s b (exprType e) $ mapAlts (flip Let e . NonRec v) alts---- | cast (case s of p -> e) co ==> case s of p -> cast e co-caseFloatCast :: MonadCatch m => Rewrite c m CoreExpr-caseFloatCast = prefixFailMsg "Case float from cast failed: " $-                withPatFailMsg (wrongExprForm "Cast (Case s bnd ty alts) co") $-    do Cast (Case s bnd _ alts) co <- idR-       let alts' = mapAlts (flip Cast co) alts-       return $ Case s bnd (coreAltsType alts') alts'---- | Float a Case whatever the context.-caseFloat :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseFloat = setFailMsg "Unsuitable expression for Case floating." $-    caseFloatApp <+ caseFloatArg <+ caseFloatCase <+ caseFloatLet <+ caseFloatCast------------------------------------------------------------------------------------ | Unfloat a Case whatever the context.-caseUnfloat :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-caseUnfloat = setFailMsg "Case unfloating failed." $-    caseUnfloatApp <+ caseUnfloatArgs---- | Unimplemented!-caseUnfloatApp :: Monad m => Rewrite c m CoreExpr-caseUnfloatApp = fail "caseUnfloatApp: TODO"--caseUnfloatArgs :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-caseUnfloatArgs = prefixFailMsg "Case unfloating into arguments failed: " $-                  withPatFailMsg (wrongExprForm "Case s v t alts") $-    do Case s wild _ty alts <- idR-       (vss, fs, argss) <- caseT mempty mempty mempty (\ _ -> altT mempty (\ _ -> idR) callT $ \ () vs (fn, args) -> (vs, fn, args))-                                                      (\ () () () alts' -> unzip3 [ (wild:vs, fn, args) | (vs,fn,args) <- alts' ])-       guardMsg (exprsEqual fs) "alternatives are not parallel in function call."-       guardMsg (all null $ zipWith intersect (map (toList.coreExprFreeVars) fs) vss) "function bound by case binders."-       let argss' = transpose argss-       guardMsg (all exprsEqual $ filter (isTyCoArg . head) argss') "function applied at different types."-       return $ mkCoreApps (head fs) [ if isTyCoArg (head args)-                                       then head args -- TODO: deal with existentials by tupling-                                       else let alts' = [ (ac, vs, arg) | ((ac,vs,_),arg) <- zip alts args ]-                                            in Case s wild (coreAltsType alts') alts'-                                     | args <- argss' ]----------------------------------------------------------------------------------caseReduce :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseReduce = setFailMsg "Unsuitable expression for Case reduction." $-             caseReduceDatacon <+ caseReduceLiteral---- NB: LitAlt cases don't do evaluation-caseReduceLiteral :: MonadCatch m => Rewrite c m CoreExpr-caseReduceLiteral = prefixFailMsg "Case reduction failed: " $-                    withPatFailMsg (wrongExprForm "Case (Lit l) v t alts") $-    do Case s wild _ alts <- idR-#if __GLASGOW_HASKELL__ > 706-       let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- S.toList (coreExprFreeVars s) ])-       case exprIsLiteral_maybe (in_scope, idUnfolding) s of-#else-       case exprIsLiteral_maybe idUnfolding s of-#endif-        Nothing -> fail "scrutinee is not a literal."-        Just l  -> do guardMsg (not (litIsLifted l)) "cannot case-reduce lifted literals" -- see Trac #5603-                      case findAlt (LitAlt l) alts of-                        Nothing          -> fail "no matching alternative."-                        Just (_, _, rhs) -> return $ mkCoreLet (NonRec wild (Lit l)) rhs---- | Case-of-known-constructor rewrite.-caseReduceDatacon :: forall c. (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-caseReduceDatacon = prefixFailMsg "Case reduction failed: " $-                    withPatFailMsg (wrongExprForm "Case e v t alts")-                    go-  where-    go :: Rewrite c HermitM CoreExpr-    go = do Case e wild _ alts <- idR-#if __GLASGOW_HASKELL__ > 706-            let in_scope = mkInScopeSet (mkVarEnv [ (v,v) | v <- S.toList (coreExprFreeVars e) ])-            case exprIsConApp_maybe (in_scope, idUnfolding) e of-#else-            case exprIsConApp_maybe idUnfolding e of-#endif-              Nothing                -> fail "head of scrutinee is not a data constructor."-              Just (dc, univTys, es) -> case findAlt (DataAlt dc) alts of-                Nothing             -> fail "no matching alternative."-                Just (dc', vs, rhs) -> -- dc' is either DEFAULT or dc-                                       -- NB: It is possible that es contains one or more existentially quantified types.-                                       let fvss    = map coreExprFreeVars $ map Type univTys ++ es-                                           shadows = [ v | (v,n) <- zip vs [1..], any (member v) (drop n fvss) ]-                                       in if | any (member wild) fvss -> alphaCaseBinder Nothing >>> go-                                             | not (null shadows)     -> caseOneR (fail "scrutinee") (fail "binder") (fail "type") (\ _ -> acceptR (\ (dc'',_,_) -> dc'' == dc') >>> alphaAltVars shadows) >>> go-                                             | null shadows           -> return $ flip mkCoreLets rhs $ zipWith NonRec (wild : vs) (e : es)--- WARNING: The alpha-renaming to avoid variable capture has not been tested.  We need testing infrastructure!---- | Case split a free variable in an expression:------ Assume expression e which mentions x :: [a]------ e ==> case x of x---         [] -> e---         (a:b) -> e-caseSplit :: TH.Name -> Rewrite c HermitM CoreExpr-caseSplit nm = do-    frees <- freeIdsT-    contextfreeT $ \ e ->-        case filter (cmpTHName2Var nm) (toList frees) of-            []    -> fail "caseSplit: provided name is not free"-            (i:_) -> do-                let (tycon, tys) = splitTyConApp (idType i)-                    dcs = tyConDataCons tycon-                    aNms = map (:[]) $ cycle ['a'..'z']-                dcsAndVars <- mapM (\dc -> do-                                        as <- sequence [ newIdH a ty | (a,ty) <- zip aNms $ dataConInstArgTys dc tys ]-                                        return (dc,as)) dcs-                return $ Case (Var i) i (exprType e) [ (DataAlt dc, as, e) | (dc,as) <- dcsAndVars ]-             -- TODO: what about when multiple results are returned?  Should we not catch that as an error?---- | Like caseSplit, but additionally inlines the constructor applications--- for each occurance of the named variable.------ > caseSplitInline nm = caseSplit nm >>> anybuR (inlineName nm)-caseSplitInline :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM Core-caseSplitInline nm = promoteR (caseSplit nm) >>> anybuR (promoteExprR $ inlineName nm)--------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Local/Cast.hs
@@ -1,120 +0,0 @@-{-# LANGUAGE MultiWayIf, FlexibleContexts #-}--module Language.HERMIT.Primitive.Local.Cast-    ( -- * Rewrites on Case Expressions-      externals-    , castElimRefl-    , castElimSym-    , castFloatApp-    , castElimSymPlus -- TODO: revisit-    ) where--import GhcPlugins-import qualified Coercion (substCo, extendTvSubst)-import Pair--import Control.Arrow-import Control.Monad--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.External--import Language.HERMIT.Primitive.Common------------------------------------------------------------------------------------ | Externals relating to Case expressions.-externals :: [External]-externals =-    [ external "cast-elim" (promoteExprR castElim :: RewriteH Core)-        [ "cast-elim-refl <+ cast-elim-sym" ] .+ Shallow .+ Bash-    , external "cast-elim-refl" (promoteExprR castElimRefl :: RewriteH Core)-        [ "cast e co ==> e ; if co is a reflexive coercion" ] .+ Shallow .+ Bash-    , external "cast-elim-sym" (promoteExprR castElimSym :: RewriteH Core)-        [ "removes pairs of symmetric casts" ]                .+ Shallow .+ Bash-    , external "cast-elim-sym-plus" (promoteExprR castElimSymPlus :: RewriteH Core)-        [ "removes pairs of symmetric casts possibly separated by let or case forms" ] .+ Deep .+ TODO-    , external "cast-float-app" (promoteExprR castFloatApp :: RewriteH Core)-        [ "(cast e (c1 -> c2)) x ==> cast (e (cast x (sym c1))) c2" ] .+ Shallow-    , external "cast-elim-unsafe" (promoteExprR castElimUnsafe :: RewriteH Core)-        [ "removes casts regardless of whether it is safe to do so" ] .+ Shallow .+ Experiment .+ Unsafe .+ TODO-    ]----------------------------------------------------------------------------------castElim :: MonadCatch m => Rewrite c m CoreExpr-castElim = setFailMsg "Cast elimination failed: " $-           castElimRefl <+ castElimSym--castElimRefl :: MonadCatch m => Rewrite c m CoreExpr-castElimRefl = prefixFailMsg "Reflexive cast elimination failed: " $-               withPatFailMsg (wrongExprForm "Cast e co") $-    do Cast e co <- idR-       Pair a b <- return $ coercionKind co-       guardMsg (eqType a b) "not a reflexive coercion."-       return e--castElimSym :: MonadCatch m => Rewrite c m CoreExpr-castElimSym = prefixFailMsg "Symmetric cast elimination failed: " $-              withPatFailMsg (wrongExprForm "Cast (Cast e co1) co2") $-    do Cast (Cast e co1) co2 <- idR-       let Pair a b   = coercionKind co1-           Pair b' a' = coercionKind co2-       guardMsg (eqType a a' && eqType b b') "coercions are not symmetric."-       return e--castFloatApp :: MonadCatch m => Rewrite c m CoreExpr-castFloatApp = prefixFailMsg "Cast float from application failed: " $-               withPatFailMsg (wrongExprForm "App (Cast e1 co) e2") $-    do App (Cast e1 co) e2 <- idR-       case co of-            TyConAppCo t [c1, c2] -> do-                True <- return (isFunTyCon t)-                return $ Cast (App e1 (Cast e2 (SymCo c1))) c2-            ForAllCo t c2 -> do-                Type x' <- return e2-                return (Cast (App e1 e2) (Coercion.substCo (Coercion.extendTvSubst emptyCvSubst t x') c2))-            _ -> fail "castFloatApp"---- TODO: revisit-castElimSymPlus :: (ExtendPath c Crumb, AddBindings c, Monad m) => Rewrite c m CoreExpr-castElimSymPlus = castT idR idR (flip go) >>> joinT-  where-      go :: Monad m => Coercion -> CoreExpr -> m CoreExpr-      go _  (Var _) = fail "no symmetric casts found"-      go _  (Lit _) = fail "no symmetric casts found"-      go _  (App _ _) = fail "app unimplemented" {- focus [0] (go c1 (add arg)) -}-      go c1 (Lam x body)-        | Just (con, [arg, res]) <- splitTyConAppCo_maybe c1-        , con == funTyCon-        , Pair arg1 arg2 <- coercionKind arg-        , arg1 `eqType` arg2 = do-            body' <- go res body-            return (Lam x body')-        | otherwise = fail "lam unimplemented" {-focus [0] (go c1 (drop arg))-}-      go c1 (Let bs body) = do body' <- go c1 body-                               return (Let bs body')-      go c1 (Case scr x _ alts) = do alts' <- sequence [liftM ((,,) c a) (go c1 b) | (c,a,b) <- alts]-                                     let t' = exprType (case head alts' of (_,_,b) -> b)-                                     return (Case scr x t' alts')-      go c1 (Cast e c2) = if sym c1 c2 then return e else fail "no symmetric casts found"-      go _  (Tick{}) = fail "unexpected tick"-      go _  (Type{}) = fail "unexpected type"-      go _  (Coercion{}) = fail "unexpected coercion"--      sym :: Coercion -> Coercion -> Bool-      sym c1 c2-        | Pair c11 c12 <- coercionKind c1,-          Pair c21 c22 <- coercionKind c2,-          c11 `eqType` c22, c21 `eqType` c12 = True-        | otherwise = False-      --sym (SymCo c1) c2 = geq c1 c2-      --sym c1 (SymCo c2) = geq c1 c2-      --sym _ _ = False---castElimUnsafe :: (ExtendPath c Crumb, Monad m) => Rewrite c m CoreExpr-castElimUnsafe = castT idR idR const-
− src/Language/HERMIT/Primitive/Local/Let.hs
@@ -1,289 +0,0 @@-{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}--module Language.HERMIT.Primitive.Local.Let-       ( -- * Rewrites on Let Expressions-         externals-       , letElim-       , letIntro-       , letFloatApp-       , letFloatArg-       , letFloatLet-       , letFloatLam-       , letFloatCase-       , letFloatCast-       , letFloatExpr-       , letFloatLetTop-       , letNonRecElim-       , letRecElim-       , letToCase-       , letUnfloat-       , letUnfloatApp-       , letUnfloatCase-       , letUnfloatLam-       , reorderNonRecLets-       )-where--import GhcPlugins--import Control.Arrow-import Control.Monad--import Data.List-import Data.Monoid-import Data.Set (member, notMember, unions, intersection, fromList, toList)-import qualified Data.Set as S--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.GHC hiding (externals)-import Language.HERMIT.Primitive.AlphaConversion hiding (externals)--import qualified Language.Haskell.TH as TH------------------------------------------------------------------------------------ | Externals relating to Let expressions.-externals :: [External]-externals =-    [ external "let-intro" (promoteExprR . letIntro :: TH.Name -> RewriteH Core)-        [ "e => (let v = e in v), name of v is provided" ]                      .+ Shallow .+ Introduce-    , external "dead-let-elimination" (promoteExprR letElim :: RewriteH Core)-        [ "dead-let-elimination removes an unused let binding."-        , "(let v = e1 in e2) ==> e2, if v is not free in e2."-        , "condition: let is not-recursive" ]                                   .+ Eval .+ Shallow .+ Bash-    , external "dead-code-elimination" (promoteExprR letElim :: RewriteH Core)-        [ "Synonym for dead-let-elimination [deprecated]" ]                     .+ Eval .+ Shallow .+ Deprecated -- TODO: delete this at some point---    , external "let-constructor-reuse" (promoteR $ not_defined "constructor-reuse" :: RewriteH Core)---        [ "let v = C v1..vn in ... C v1..vn ... ==> let v = C v1..vn in ... v ..., fails otherwise" ] .+ Eval-    , external "let-float-app" (promoteExprR letFloatApp :: RewriteH Core)-        [ "(let v = ev in e) x ==> let v = ev in e x" ]                         .+ Commute .+ Shallow .+ Bash-    , external "let-float-arg" (promoteExprR letFloatArg :: RewriteH Core)-        [ "f (let v = ev in e) ==> let v = ev in f e" ]                         .+ Commute .+ Shallow .+ Bash-    , external "let-float-lam" (promoteExprR letFloatLam :: RewriteH Core)-        [ "(\\ v1 -> let v2 = e1 in e2)  ==>  let v2 = e1 in (\\ v1 -> e2), if v1 is not free in e2."-        , "If v1 = v2 then v1 will be alpha-renamed." ]                         .+ Commute .+ Shallow .+ Bash-    , external "let-float-let" (promoteExprR letFloatLet :: RewriteH Core)-        [ "let v = (let w = ew in ev) in e ==> let w = ew in let v = ev in e" ] .+ Commute .+ Shallow .+ Bash-    , external "let-float-case" (promoteExprR letFloatCase :: RewriteH Core)-        [ "case (let v = ev in e) of ... ==> let v = ev in case e of ..." ]     .+ Commute .+ Shallow .+ Eval .+ Bash-    , external "let-float-cast" (promoteExprR letFloatCast :: RewriteH Core)-        [ "cast (let bnds in e) co ==> let bnds in cast e co" ]                 .+ Shallow-    , external "let-float-top" (promoteProgR letFloatLetTop :: RewriteH Core)-        [ "v = (let w = ew in ev) : bds ==> w = ew : v = ev : bds" ]            .+ Commute .+ Shallow .+ Bash-    , external "let-float" (promoteProgR letFloatLetTop <+ promoteExprR letFloatExpr :: RewriteH Core)-        [ "Float a Let whatever the context." ]                                 .+ Commute .+ Shallow .+ Bash-    , external "let-to-case" (promoteExprR letToCase :: RewriteH Core)-        [ "let v = ev in e ==> case ev of v -> e" ]                             .+ Commute .+ Shallow .+ PreCondition---    , external "let-to-case-unbox" (promoteR $ not_defined "let-to-case-unbox" :: RewriteH Core)---        [ "let v = ev in e ==> case ev of C v1..vn -> let v = C v1..vn in e" ]-    , external "let-unfloat" (promoteExprR letUnfloat :: RewriteH Core)-        [ "Unfloat a let if possible." ]                                        .+ Commute .+ Shallow-    , external "let-unfloat-app" ((promoteExprR letUnfloatApp >+> anybuR (promoteExprR letElim)) :: RewriteH Core)-        [ "let v = ev in f a ==> (let v = ev in f) (let v = ev in a)" ]         .+ Commute .+ Shallow-    , external "let-unfloat-case" ((promoteExprR letUnfloatCase >+> anybuR (promoteExprR letElim)) :: RewriteH Core)-        [ "let v = ev in case s of p -> e ==> case (let v = ev in s) of p -> let v = ev in e"-        , "if v does not shadow a pattern binder in p" ]                        .+ Commute .+ Shallow-    , external "let-unfloat-lam" ((promoteExprR letUnfloatLam >+> anybuR (promoteExprR letElim)) :: RewriteH Core)-        [ "let v = ev in \\ x -> e ==> \\ x -> let v = ev in e"-        , "if v does not shadow x" ]                                            .+ Commute .+ Shallow-    , external "reorder-lets" (promoteExprR . reorderNonRecLets :: [TH.Name] -> RewriteH Core)-        [ "Re-order a sequence of nested non-recursive let bindings."-        , "The argument list should contain the let-bound variables, in the desired order." ]-    ]------------------------------------------------------------------------------------------------- | @e@ ==> @(let v = e in v)@, name of v is provided-letIntro :: TH.Name -> Rewrite c HermitM CoreExpr-letIntro nm = prefixFailMsg "Let-introduction failed: " $-              contextfreeT $ \ e -> do guardMsg (not $ isTypeArg e) "let expressions may not return a type."-                                       v <- newIdH (show nm) (exprTypeOrKind e)-                                       return $ Let (NonRec v e) (Var v)--letElim :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-letElim = letNonRecElim <+ letRecElim---- | Remove an unused non-recursive let binding.---   @let v = E1 in E2@ ==> @E2@, if @v@ is not free in @E2@-letNonRecElim :: MonadCatch m => Rewrite c m CoreExpr-letNonRecElim = prefixFailMsg "Dead-let-elimination failed: " $-                withPatFailMsg (wrongExprForm "Let (NonRec v e1) e2") $-                do Let (NonRec v _) e <- idR-                   guardMsg (v `notMember` coreExprFreeVars e) "let-bound variable appears in the expression."-                   return e---- TODO: find the GHC way to do this, as this implementation will be defeated by mutual recursion--- | Remove all unused recursive let bindings in the current group.-letRecElim :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-letRecElim = prefixFailMsg "Dead-let-elimination failed: " $ do-    Let (Rec bnds) body <- idR-    (vsAndFrees, bodyFrees) <- letRecDefT (\ _ -> (idR,freeVarsT)) freeVarsT (,)-    -- binder is alive if it is found free anywhere but its own rhs-    let living = [ v-                 | (v,_) <- vsAndFrees-                 , v `member` bodyFrees || v `member` unions [ fs | (v',fs) <- vsAndFrees, v' /= v ]-                 ]-    if null living-        then return body-        else if length living == length bnds-                then fail "no dead code."-                else return $ Let (Rec [ (v,rhs) | (v,rhs) <- bnds, v `elem` living ]) body---- | @let v = ev in e@ ==> @case ev of v -> e@-letToCase :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letToCase = prefixFailMsg "Converting Let to Case failed: " $-            withPatFailMsg (wrongExprForm "Let (NonRec v e1) e2") $-  do Let (NonRec v ev) _ <- idR-     guardMsg (not $ isTyCoArg ev) "cannot case on a type or coercion."-     nameModifier <- freshNameGenT Nothing-     caseBndr <- constT (cloneVarH nameModifier v)-     letT mempty (replaceVarR v caseBndr) $ \ () e' -> Case ev caseBndr (varType v) [(DEFAULT, [], e')]------------------------------------------------------------------------------------------------- | @(let v = ev in e) x@ ==> @let v = ev in e x@-letFloatApp :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letFloatApp = prefixFailMsg "Let floating from App function failed: " $-  do vs <- appT (liftM fromList letVarsT) freeVarsT intersection-     let letAction = if S.null vs then idR else alphaLet-     appT letAction idR $ \ (Let bnds e) x -> Let bnds $ App e x---- | @f (let v = ev in e)@ ==> @let v = ev in f e@-letFloatArg :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letFloatArg = prefixFailMsg "Let floating from App argument failed: " $-  do vs <- appT freeVarsT (liftM fromList letVarsT) intersection-     let letAction = if S.null vs then idR else alphaLet-     appT idR letAction $ \ f (Let bnds e) -> Let bnds $ App f e---- | @let v = (let w = ew in ev) in e@ ==> @let w = ew in let v = ev in e@-letFloatLet :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letFloatLet = prefixFailMsg "Let floating from Let failed: " $-  do vs <- letNonRecT mempty (liftM fromList letVarsT) freeVarsT (\ () -> intersection)-     let bdsAction = if S.null vs then idR else nonRecAllR idR alphaLet-     letT bdsAction idR $ \ (NonRec v (Let bds ev)) e -> Let bds $ Let (NonRec v ev) e---- | @(\ v1 -> let v2 = e1 in e2)@  ==>  @let v2 = e1 in (\ v1 -> e2)@---   Fails if @v1@ occurs in @e1@.---   If @v1@ = @v2@ then @v1@ will be alpha-renamed.-letFloatLam :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letFloatLam = prefixFailMsg "Let floating from Lam failed: " $-              withPatFailMsg (wrongExprForm "Lam v1 (Let (NonRec v2 e1) e2)") $-  do Lam v1 (Let (NonRec v2 e1) e2) <- idR-     guardMsg (v1 `notMember` coreExprFreeVars e1) $ var2String v1 ++ " occurs in the definition of " ++ var2String v2 ++ "."-     if v1 == v2-      then alphaLam Nothing >>> letFloatLam-      else return (Let (NonRec v2 e1) (Lam v1 e2))---- | @case (let bnds in e) of wild alts@ ==> @let bnds in (case e of wild alts)@---   Fails if any variables bound in @bnds@ occurs in @alts@.-letFloatCase :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letFloatCase = prefixFailMsg "Let floating from Case failed: " $-  do captures <- caseT letVarsT-                       idR-                       idR-                       (\ _ -> altFreeVarsExclWildT)-                       (\ vs wild _ fs -> fromList vs `intersection` unions (map ($ wild) fs))-     caseT (if S.null captures then idR else alphaLetVars $ toList captures)-           idR-           idR-           (const idR)-           (\ (Let bnds e) wild ty alts -> Let bnds (Case e wild ty alts))---- | @cast (let bnds in e) co@ ==> @let bnds in cast e co@-letFloatCast :: MonadCatch m => Rewrite c m CoreExpr-letFloatCast = prefixFailMsg "Let floating from Cast failed: " $-               withPatFailMsg (wrongExprForm "Cast (Let bnds e) co") $-  do Cast (Let bnds e) co <- idR-     return (Let bnds (Cast e co))---- | Float a 'Let' through an expression, whatever the context.-letFloatExpr :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-letFloatExpr = setFailMsg "Unsuitable expression for Let floating." $-               letFloatArg <+ letFloatApp <+ letFloatLet <+ letFloatLam <+ letFloatCase <+ letFloatCast---- | @ProgCons (NonRec v (Let (NonRec w ew) ev)) p@ ==> @ProgCons (NonRec w ew) (ProgCons (NonRec v ev) p)@-letFloatLetTop :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreProg-letFloatLetTop = prefixFailMsg "Let floating to top level failed: " $-                 withPatFailMsg (wrongExprForm "NonRec v (Let (NonRec w ew) ev) `ProgCons` p") $-  do NonRec v (Let (NonRec w ew) ev) `ProgCons` p <- idR-     guardMsg (not $ isTyCoArg ew) "type and coercion bindings are not allowed at the top level."-     return (NonRec w ew `ProgCons` NonRec v ev `ProgCons` p)------------------------------------------------------------------------------------------------- | Unfloat a 'Let' if possible.-letUnfloat :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-letUnfloat = letUnfloatCase <+ letUnfloatApp <+ letUnfloatLam---- | @let v = ev in case s of p -> e@ ==> @case (let v = ev in s) of p -> let v = ev in e@,---   if @v@ does not shadow a pattern binder in @p@-letUnfloatCase :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-letUnfloatCase = prefixFailMsg "Let unfloating from case failed: " $-                 withPatFailMsg (wrongExprForm "Let bnds (Case s w ty alts)") $-  do Let bnds (Case s w ty alts) <- idR-     captured <- letT bindVarsT caseVarsT intersect-     guardMsg (null captured) "let bindings would capture case pattern bindings."-     unbound <- letT bindVarsT (caseT mempty mempty freeTyVarsT (const mempty) $ \ () () vs (_::[()]) -> toList vs) intersect-     guardMsg (null unbound) "type variables in case signature would become unbound."-     return $ Case (Let bnds s) w ty $ mapAlts (Let bnds) alts---- | @let v = ev in f a@ ==> @(let v = ev in f) (let v = ev in a)@-letUnfloatApp :: MonadCatch m => Rewrite c m CoreExpr-letUnfloatApp = prefixFailMsg "Let unfloating from app failed: " $-                withPatFailMsg (wrongExprForm "Let bnds (App e1 e2)") $-  do Let bnds (App e1 e2) <- idR-     return $ App (Let bnds e1) (Let bnds e2)---- | @let v = ev in \ x -> e@ ==> @\x -> let v = ev in e@---   if @v@ does not shadow @x@-letUnfloatLam :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Rewrite c m CoreExpr-letUnfloatLam = prefixFailMsg "Let unfloating from lambda failed: " $-                withPatFailMsg (wrongExprForm "Let bnds (Lam v e)") $-  do Let bnds (Lam v e) <- idR-     safe <- letT bindVarsT lamVarT $ flip notElem-     guardMsg safe "let bindings would capture lambda binding."-     return $ Lam v $ Let bnds e------------------------------------------------------------------------------------------------- | Re-order a sequence of nested non-recursive let bindings.---   The argument list should contain the let-bound variables, in the desired order.-reorderNonRecLets :: MonadCatch m => [TH.Name] -> Rewrite c m CoreExpr-reorderNonRecLets ns = prefixFailMsg "Reorder lets failed: " $-                 do guardMsg (not $ null ns) "no names given."-                    guardMsg (nodups ns) "duplicate names given."-                    e <- idR-                    (ves,x) <- setFailMsg "insufficient non-recursive lets." $ takeNonRecLets (length ns) e-                    guardMsg (noneFreeIn ves) "some of the bound variables appear in the right-hand-sides."-                    e' <- mkNonRecLets `liftM` mapM (lookupName ves) ns `ap` return x-                    guardMsg (not $ exprEqual e e') "bindings already in specified order."-                    return e'--  where-    takeNonRecLets :: Monad m => Int -> CoreExpr -> m ([(Var,CoreExpr)],CoreExpr)-    takeNonRecLets 0 x                      = return ([],x)-    takeNonRecLets n (Let (NonRec v1 e1) x) = first ((v1,e1):) `liftM` takeNonRecLets (n-1) x-    takeNonRecLets _ _                      = fail "insufficient non-recursive lets."--    noneFreeIn :: [(Var,CoreExpr)] -> Bool-    noneFreeIn ves = let (vs,es) = unzip ves-                      in all (`notMember` unions (map coreExprFreeVars es)) vs--    lookupName :: Monad m => [(Var,CoreExpr)] -> TH.Name -> m (Var,CoreExpr)-    lookupName ves nm = case filter (cmpTHName2Var nm . fst) ves of-                          []   -> fail $ "name " ++ show nm ++ " not matched."-                          [ve] -> return ve-                          _    -> fail $ "multiple matches for " ++ show nm ++ "."--    mkNonRecLets :: [(Var,CoreExpr)] -> CoreExpr -> CoreExpr-    mkNonRecLets []          x  = x-    mkNonRecLets ((v,e):ves) x  = Let (NonRec v e) (mkNonRecLets ves x)---------------------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Navigation.hs
@@ -1,157 +0,0 @@-{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}--module Language.HERMIT.Primitive.Navigation-       ( -- * Navigation-         externals-       , bindGroup-       , namedBinding-       , bindingGroupOf-       , considerName-       , rhsOf-       , considerTargets-       , Considerable(..)-       , considerables-       , considerConstructT-       , nthArgPath-       )-where--import Data.Monoid (mempty)--import Control.Arrow (arr)--import GhcPlugins as GHC--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.GHC--import Language.HERMIT.Primitive.Navigation.Crumbs--import qualified Language.Haskell.TH as TH--------------------------------------------------------------------------------------------- | 'External's involving navigating to named entities.-externals :: [External]-externals = crumbExternals ++ map (.+ Navigation)-            [-              external "consider" (considerName :: TH.Name -> TranslateH Core PathH)-                [ "consider '<v> focuses on the definition of <v>" ]-            , external "consider" (considerConstruct :: String -> TranslateH Core PathH)-                [ "consider <c> focuses on the first construct <c>.",-                  recognizedConsiderables]-            , external "rhs-of" (rhsOf :: TH.Name -> TranslateH Core PathH)-                [ "rhs-of '<v> focuses on the right-hand-side of the definition of <v>" ]-            , external "binding-group-of" (bindingGroupOf :: TH.Name -> TranslateH Core PathH)-                [ "binding-group-of '<v> focuses on the binding group that binds the variable <v>" ]-            , external "arg" (promoteExprT . nthArgPath :: Int -> TranslateH Core PathH)-                [ "arg n focuses on the (n-1)th argument of a nested application." ]-            ]--------------------------------------------------------------------------------------------- | Find the path to the RHS of the binding group of the given name.-bindingGroupOf :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => TH.Name -> Translate c m Core PathH-bindingGroupOf = oneNonEmptyPathToT . bindGroup---- | Find the path to the definiiton of the provided name.-considerName :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => TH.Name -> Translate c m Core PathH-considerName = oneNonEmptyPathToT . namedBinding---- | Find the path to the RHS of the definition of the given name.-rhsOf :: (ExtendPath c Crumb, AddBindings c, ReadPath c Crumb, MonadCatch m) => TH.Name -> Translate c m Core PathH-rhsOf nm = do p  <- onePathToT (namedBinding nm)-              cr <- pathT p (   promoteBindT (nonRecT mempty lastCrumbT $ \ () cr -> cr)-                             <+ promoteDefT  (defT    mempty lastCrumbT $ \ () cr -> cr)-                            )-              return (p ++ [cr])--- TODO: The new definition is inefficient.  Try and improve it.  May need to generalise the KURE "onePathTo" combinators.--- rhsOf nm = onePathToT (namedBinding nm) >>^ (++ [0])---- | Verify that this is a binding group defining the given name.-bindGroup :: TH.Name -> Core -> Bool-bindGroup nm (BindCore (NonRec v _))  =  nm `cmpTHName2Var` v-bindGroup nm (BindCore (Rec bds))     =  any (cmpTHName2Var nm . fst) bds-bindGroup _  _                        =  False---- | Verify that this is the definition of the given name.-namedBinding :: TH.Name -> Core -> Bool-namedBinding nm (BindCore (NonRec v _))  =  nm `cmpTHName2Var` v-namedBinding nm (DefCore (Def v _))      =  nm `cmpTHName2Var` v-namedBinding _  _                        =  False---- | Find the names of all the variables that could be targets of \"consider\".-considerTargets :: forall c m. (ExtendPath c Crumb, AddBindings c, MonadCatch m) => Translate c m Core [String]-considerTargets = allT $ collectT (promoteBindT nonRec <+ promoteDefT def)-    where-      nonRec :: Translate c m CoreBind String-      nonRec = nonRecT (arr var2String) idR const--      def :: Translate c m CoreDef String-      def = defT (arr var2String) idR const---- | Language constructs that can be zoomed to.-data Considerable = Binding | Definition | CaseAlt | Variable | Literal | Application | Lambda | LetIn | CaseOf | Casty | Ticky | TypeVar | Coerce--recognizedConsiderables :: String-recognizedConsiderables = "Recognized constructs are: " ++ show (map fst considerables)---- | Lookup table for constructs that can be considered; the keys are the arguments the user can give to the \"consider\" command.-considerables ::  [(String,Considerable)]-considerables =   [ ("bind",Binding)-                  , ("def",Definition)-                  , ("alt",CaseAlt)-                  , ("var",Variable)-                  , ("lit",Literal)-                  , ("app",Application)-                  , ("lam",Lambda)-                  , ("let",LetIn)-                  , ("case",CaseOf)-                  , ("cast",Casty)-                  , ("tick",Ticky)-                  , ("type",TypeVar)-                  , ("coerce",Coerce)-                  ]--considerConstruct :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => String -> Translate c m Core PathH-considerConstruct str = case string2considerable str of-                          Nothing -> fail $ "Unrecognized construct \"" ++ str ++ "\". " ++ recognizedConsiderables ++ ".  Or did you mean \"consider '" ++ str ++ "\"?"-                          Just c  -> considerConstructT c---- | Find the path to the first matching construct.-considerConstructT :: (AddBindings c, ExtendPath c Crumb, ReadPath c Crumb, MonadCatch m) => Considerable -> Translate c m Core PathH-considerConstructT = oneNonEmptyPathToT . underConsideration--string2considerable :: String -> Maybe Considerable-string2considerable = flip lookup considerables--underConsideration :: Considerable -> Core -> Bool-underConsideration Binding     (BindCore _)               = True-underConsideration Definition  (BindCore (NonRec _ _))    = True-underConsideration Definition  (DefCore _)                = True-underConsideration CaseAlt     (AltCore _)                = True-underConsideration Variable    (ExprCore (Var _))         = True-underConsideration Literal     (ExprCore (Lit _))         = True-underConsideration Application (ExprCore (App _ _))       = True-underConsideration Lambda      (ExprCore (Lam _ _))       = True-underConsideration LetIn       (ExprCore (Let _ _))       = True-underConsideration CaseOf      (ExprCore (Case _ _ _ _))  = True-underConsideration Casty       (ExprCore (Cast _ _))      = True-underConsideration Ticky       (ExprCore (Tick _ _))      = True-underConsideration TypeVar     (ExprCore (Type _))        = True-underConsideration Coerce      (ExprCore (Coercion _))    = True-underConsideration _           _                          = False--------------------------------------------------------------------------------------------- | Construct a path to the (n-1)th argument in a nested sequence of 'App's.-nthArgPath :: Monad m => Int -> Translate c m CoreExpr PathH-nthArgPath n = contextfreeT $ \ e -> let funCrumbs = appCount e - 1 - n-                                      in if funCrumbs < 0-                                          then fail ("Argument " ++ show n ++ " does not exist.")-                                          else return (replicate funCrumbs App_Fun ++ [App_Arg])-----------------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Navigation/Crumbs.hs
@@ -1,100 +0,0 @@-module Language.HERMIT.Primitive.Navigation.Crumbs-       ( -- * Navigating Using Crumbs-         crumbExternals-       )-where--import Language.HERMIT.Core-import Language.HERMIT.External--------------------------------------------------------------------------------------------- | 'External's for individual 'Crumb's.-crumbExternals :: [External]-crumbExternals = map (.+ Navigation)-            [-              external "prog" ModGuts_Prog-                [ "Descend into the program within a module." ]-            , external "prog-head" ProgCons_Head-                [ "Descend into the first binding group in a program." ]-            , external "prog-tail" ProgCons_Tail-                [ "Descend into the tail of the program." ]-            , external "nonrec-rhs" NonRec_RHS-                [ "Descend into the right-hand side of a non-recursive binding." ]-            , external "rec-def" Rec_Def-                [ "Descend into the (n-1)th definition in a recursive binding group." ]-            , external "def-rhs" Def_RHS-                [ "Descend into the right-hand side of a recursive definition." ]-            , external "app-fun" App_Fun-                [ "Descend into the function in an application." ]-            , external "app-arg" App_Arg-                [ "Descend into the argument in an application." ]-            , external "lam-body" Lam_Body-                [ "Descend into the body of a lambda." ]-            , external "let-bind" Let_Bind-                [ "Descend into the binding group of a let expression." ]-            , external "let-body" Let_Body-                [ "Descend into the body of a let expression." ]-            , external "case-expr" Case_Scrutinee-                [ "Descend into the scrutinised expression in a case expression." ]-            , external "case-type" Case_Type-                [ "Descend into the type of a case expression." ]-            , external "case-alt" Case_Alt-                [ "Descend into the (n-1)th alternative in a case expression." ]-            , external "cast-expr" Cast_Expr-                [ "Descend into the expression in a cast." ]-            , external "cast-co" Cast_Co-                [ "Descend into the coercion in a cast." ]-            , external "tick-expr" Tick_Expr-                [ "Descend into the expression in a tick." ]-            , external "alt-rhs" Alt_RHS-                [ "Descend into the right-hand side of a case alternative." ]-            , external "type" Type_Type-                [ "Descend into the type within a type expression." ]-            , external "coercion" Co_Co-                [ "Descend into the coercion within a coercion expression." ]-            , external "appTy-fun" AppTy_Fun-                [ "Descend into the type function in a type application." ]-            , external "appTy-arg" AppTy_Fun-                [ "Descend into the type argument in a type application." ]-            , external "tyCon-arg" TyConApp_Arg-                [ "Descend into the (n-1)th argument of a type constructor application." ]-            , external "fun-dom" FunTy_Dom-                [ "Descend into the domain of a function type." ]-            , external "fun-cod" FunTy_CoDom-                [ "Descend into the codomain of a function type." ]-            , external "forall-body" ForAllTy_Body-                [ "Descend into the body of a forall type." ]-            , external "refl-type" Refl_Type-                [ "Descend into the (n-1)th argument of a type constructor coercion." ]-            , external "coCon-arg" TyConAppCo_Arg-                [ "Descend into the function of a coercion application." ]-            , external "appCo-fun" AppCo_Fun-                [ "Descend into the coercion function in a coercion application." ]-            , external "appCo-arg" AppCo_Arg-                [ "Descend into the coercion argument in a coercion application." ]-            , external "coForall-body" ForAllCo_Body-                [ "Descend into the body of a forall coercion." ]-            , external "axiom-inst" AxiomInstCo_Arg-                [ "Descend into the (n-1)th argument of a coercion axiom instantiation." ]-            , external "unsafe-left" UnsafeCo_Left-                [ "Descend into the left-hand type of an unsafe coercion." ]-            , external "unsafe-right" UnsafeCo_Right-                [ "Descend into the right-hand type of an unsafe coercion." ]-            , external "sym-co" SymCo_Co-                [ "Descend into the coercion within a symmetric coercion." ]-            , external "trans-left" TransCo_Left-                [ "Descend into the left-hand type of a transitive coercion." ]-            , external "trans-right" TransCo_Right-                [ "Descend into the right-hand type of a transitive coercion." ]-            , external "nth-co" NthCo_Co-                [ "Descend into the coercion within an nth projection coercion." ]-            , external "inst-co" InstCo_Co-                [ "Descend into the coercion within a coercion instantiation." ]-            , external "inst-type" InstCo_Type-                [ "Descend into the type within a coercion instantiation." ]-            , external "lr-co" LRCo_Co-                [ "Descend into the coercion within a left/right projection coercion." ]-            ]-----------------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/New.hs
@@ -1,190 +0,0 @@-{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}---- Placeholder for new prims-module Language.HERMIT.Primitive.New where--import GhcPlugins as GHC hiding (varName)--import Control.Arrow-import Control.Monad (liftM)--import Data.List(transpose)-import Data.Set (intersection, unions, fromList, toList)-import qualified Data.Set as S--import Language.HERMIT.Context-import Language.HERMIT.Core-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.External-import Language.HERMIT.GHC-import Language.HERMIT.ParserCore--import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.GHC-import Language.HERMIT.Primitive.Local-import Language.HERMIT.Primitive.Inline-import Language.HERMIT.Primitive.Unfold--- import Language.HERMIT.Primitive.Debug--import qualified Language.Haskell.TH as TH---externals ::  [External]-externals = map ((.+ Experiment) . (.+ TODO))-         [ external "test" (testQuery :: RewriteH Core -> TranslateH Core String)-                [ "determines if a rewrite could be successfully applied" ]-         , external "push" (promoteExprR . push :: TH.Name -> RewriteH Core)-                [ "push a function <f> into argument."-                , "Unsafe if f is not strict." ] .+ PreCondition-         , external "var" (promoteExprT . isVar :: TH.Name -> TranslateH Core ())-                 [ "var '<v> returns successfully for variable v, and fails otherwise.",-                   "Useful in combination with \"when\", as in: when (var v) r" ] .+ Predicate-         , external "simplify" (simplifyR :: RewriteH Core)-                [ "innermost (unfold 'id <+ unfold '$ <+ unfold '. <+ beta-reduce-plus <+ safe-let-subst <+ case-reduce <+ dead-let-elimination)" ] .+ Bash-         , external "let-tuple" (promoteExprR . letTupleR :: TH.Name -> RewriteH Core)-                [ "let x = e1 in (let y = e2 in e) ==> let t = (e1,e2) in (let x = fst t in (let y = snd t in e))" ]-         , external "static-arg" (promoteDefR staticArg :: RewriteH Core)-                [ "perform the static argument transformation on a recursive function" ]-         , external "unsafe-replace" (promoteExprR . unsafeReplace :: CoreString -> RewriteH Core)-                [ "replace the currently focused expression with a new expression" ] .+ Unsafe-         , external "unsafe-replace" (promoteExprR . unsafeReplaceStash :: String -> RewriteH Core)-                [ "replace the currently focused expression with an expression from the stash"-                , "DOES NOT ensure expressions have the same type, or that free variables in the replacement expression are in scope" ] .+ Unsafe-         , external "inline-all" (inlineAll :: [TH.Name] -> RewriteH Core)-                [ "inline all named functions in a bottom-up manner" ]-         ]----------------------------------------------------------------------------------------------------------isVar :: (ExtendPath c Crumb, AddBindings c, MonadCatch m) => TH.Name -> Translate c m CoreExpr ()-isVar nm = let matchName = arr (cmpTHName2Var nm)-            in (varT matchName <+ typeT (tyVarT matchName)) >>= guardM----------------------------------------------------------------------------------------------------------simplifyR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM Core-simplifyR = setFailMsg "Simplify failed: nothing to simplify." $-    innermostR (promoteExprR (unfoldNameR (TH.mkName "$")-                           <+ unfoldNameR (TH.mkName ".")-                           <+ unfoldNameR (TH.mkName "id")-                           <+ betaReducePlus-                           <+ safeLetSubstR-                           <+ caseReduce-                           <+ letElim))--collectLets :: CoreExpr -> ([(Var, CoreExpr)],CoreExpr)-collectLets (Let (NonRec x e1) e2) = let (bs,expr) = collectLets e2 in ((x,e1):bs, expr)-collectLets expr                   = ([],expr)---- | Combine nested non-recursive lets into case of a tuple.-letTupleR :: TH.Name -> Rewrite c HermitM CoreExpr-letTupleR nm = prefixFailMsg "Let-tuple failed: " $-  do (bnds, body) <- arr collectLets-     let numBnds = length bnds-     guardMsg (numBnds > 1) "at least two non-recursive let bindings required."--     let (vs, rhss)  = unzip bnds-     guardMsg (all isId vs) "cannot tuple type variables." -- TODO: it'd be better if collectLets stopped on reaching a TyVar--     -- check if tupling the bindings would cause unbound variables-     let-         frees    = map coreExprFreeVars (drop 1 rhss)-         used     = unions $ zipWith intersection (map (fromList . (`take` vs)) [1..]) frees-     if S.null used-       then let rhs = mkCoreTup rhss-            in constT $ do wild <- newIdH (show nm) (exprType rhs)-                           return $ mkSmallTupleCase vs body wild rhs--       else fail $ "the following bound variables are used in subsequent bindings: " ++ showVars (toList used)---- Others--- let v = E1 in E2 E3 <=> (let v = E1 in E2) E3--- let v = E1 in E2 E3 <=> E2 (let v = E1 in E3)--staticArg :: forall c. (ExtendPath c Crumb, AddBindings c) => Rewrite c HermitM CoreDef-staticArg = prefixFailMsg "static-arg failed: " $ do-    Def f rhs <- idR-    let (bnds, body) = collectBinders rhs-    guardMsg (notNull bnds) "rhs is not a function"-    contextonlyT $ \ c -> do-        let bodyContext = foldl (flip addLambdaBinding) c bnds--        callPats <- apply (callsT (var2THName f) (callT >>> arr snd)) bodyContext (ExprCore body)-        let argExprs = transpose callPats-            numCalls = length callPats-            -- ensure argument is present in every call (partial applications boo)-            (ps,dbnds) = unzip [ (i,b) | (i,b,exprs) <- zip3 [0..] bnds $ argExprs ++ repeat []-                                       , length exprs /= numCalls || isDynamic b exprs-                                       ]--            isDynamic _ []                      = False     -- all were static, so static-            isDynamic b ((Var b'):es)           | b == b' = isDynamic b es-            isDynamic b ((Type (TyVarTy v)):es) | b == v  = isDynamic b es-            isDynamic _ _                       = True      -- not a simple repass, so dynamic--        wkr <- newIdH (var2String f ++ "'") (exprType (mkCoreLams dbnds body))--        let replaceCall :: Monad m => Rewrite c m CoreExpr-            replaceCall = do-                (_,exprs) <- callT-                return $ mkApps (Var wkr) [ e | (p,e) <- zip [0..] exprs, (p::Int) `elem` ps ]--        ExprCore body' <- apply (callsR (var2THName f) replaceCall) bodyContext (ExprCore body)--        return $ Def f $ mkCoreLams bnds $ Let (Rec [(wkr, mkCoreLams dbnds body')])-                                             $ mkApps (Var wkr) (varsToCoreExprs dbnds)----------------------------------------------------------------------------------------------------------testQuery :: MonadCatch m => Rewrite c m Core -> Translate c m Core String-testQuery r = f `liftM` testM r-  where-    f True  = "Rewrite would succeed."-    f False = "Rewrite would fail."------------------------------------------------------------------------------------------------------------ | Push a function through a Case or Let expression.---   Unsafe if the function is not strict.-push :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM CoreExpr-push nm = prefixFailMsg "push failed: " $-     do e <- idR-        case collectArgs e of-          (Var v,args) -> do-                  guardMsg (nm `cmpTHName2Var` v) $ "cannot find name " ++ show nm-                  guardMsg (not $ null args) $ "no argument for " ++ show nm-                  guardMsg (all isTypeArg $ init args) $ "initial arguments are not type arguments for " ++ show nm-                  case last args of-                     Case {} -> caseFloatArg-                     Let {}  -> letFloatArg-                     _       -> fail "argument is not a Case or Let."-          _ -> fail "no function to match."------------------------------------------------------------------------------------------------------------ The types of these can probably be generalised after the Core Parser is generalised.--parseCoreExprT :: CoreString -> TranslateH a CoreExpr-parseCoreExprT = contextonlyT . parseCore--unsafeReplace :: CoreString -> RewriteH CoreExpr-unsafeReplace core =-    translate $ \ c e -> do-        e' <- parseCore core c-        guardMsg (eqType (exprType e) (exprType e')) "expression types differ."-        return e'--unsafeReplaceStash :: String -> RewriteH CoreExpr-unsafeReplaceStash label = prefixFailMsg "unsafe-replace failed: " $-    contextfreeT $ \ e -> do-        Def _ rhs <- lookupDef label-        guardMsg (eqType (exprType e) (exprType rhs)) "expression types differ."-        return rhs----------------------------------------------------------------------------------------------------------inlineAll :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [TH.Name] -> Rewrite c HermitM Core-inlineAll = innermostR . foldr (\ nm rr -> promoteExprR (inlineName nm) <+ rr) (fail "inline-all: nothing to do")--------------------------------------------------------------------------------------------------------
− src/Language/HERMIT/Primitive/Unfold.hs
@@ -1,151 +0,0 @@-{-# LANGUAGE FlexibleContexts, ScopedTypeVariables, TupleSections, LambdaCase #-}-module Language.HERMIT.Primitive.Unfold-    ( externals-    , cleanupUnfoldR-    , rememberR-    , showStashT-    , unfoldR-    , unfoldPredR-    , unfoldNameR-    , unfoldAnyR-    , unfoldSaturatedR-    , unfoldStashR-    , specializeR-    ) where--import GhcPlugins hiding (empty)-import Control.Applicative-import Control.Arrow-import Control.Monad--import qualified Data.Map as Map-import Data.Set (toList)--import qualified Language.Haskell.TH as TH--import Language.HERMIT.PrettyPrinter.Common (DocH, PrettyH, TranslateDocH(..), initPrettyC)--import Language.HERMIT.Primitive.Common-import Language.HERMIT.Primitive.GHC hiding (externals)-import Language.HERMIT.Primitive.Inline hiding (externals)--import Language.HERMIT.Core-import Language.HERMIT.Context-import Language.HERMIT.Kure-import Language.HERMIT.Monad-import Language.HERMIT.External-import Language.HERMIT.GHC--import Prelude hiding (exp)--import qualified Text.PrettyPrint.MarkedHughesPJ as PP----------------------------------------------------------------------------externals :: [External]-externals =-    [ external "cleanup-unfold" (promoteExprR cleanupUnfoldR :: RewriteH Core)-        [ "Clean up immediately nested fully-applied lambdas, from the bottom up" ] .+ Deep-    , external "remember" (rememberR :: Label -> RewriteH Core)-        [ "Remember the current binding, allowing it to be folded/unfolded in the future." ] .+ Context-    , external "unfold" (promoteExprR . unfoldStashR :: String -> RewriteH Core)-        [ "Unfold a remembered definition." ] .+ Deep .+ Context-    , external "unfold" (promoteExprR unfoldR :: RewriteH Core)-        [ "In application f x y z, unfold f." ] .+ Deep .+ Context-    , external "unfold" (promoteExprR . unfoldNameR :: TH.Name -> RewriteH Core)-        [ "Inline a definition, and apply the arguments; traditional unfold" ] .+ Deep .+ Context-    , external "unfold-saturated" (promoteExprR unfoldSaturatedR :: RewriteH Core)-        [ "Unfold a definition only if the function is fulled applied." ] .+ Deep .+ Context-    , external "specialize" (promoteExprR specializeR :: RewriteH Core)-        [ "Specialize an application to its type and coercion arguments." ] .+ Deep .+ Context-    , external "unfold-rule" ((\ nm -> promoteExprR (rule nm >>> cleanupUnfoldR)) :: String -> RewriteH Core)-        [ "Apply a named GHC rule" ] .+ Deep .+ Context .+ TODO -- TODO: does not work with rules with no arguments-    , external "show-remembered" (TranslateDocH showStashT :: TranslateDocH CoreTC)-        [ "Display all remembered definitions." ]-    ]------------------------------------------------------------------------------ | cleanupUnfoldR cleans a unfold operation---  (for example, an inline or rule application)--- It is used at the level of the top-redex.--- Invariant: will not introduce let bindings-cleanupUnfoldR :: MonadCatch m => Rewrite c m CoreExpr-cleanupUnfoldR = do-    (f, args) <- callT <+ (idR >>> arr (,[]))-    let (vs, body) = collectBinders f-        lenargs = length args-        lenvs = length vs-        comp = compare lenargs lenvs-        body' = case comp of-                    LT -> mkCoreLams (drop lenargs vs) body-                    _  -> body-        bnds = zipWith NonRec vs args-    body'' <- contextonlyT $ \ c -> do-        apply (andR $ replicate (length bnds) letSubstR) c $ mkCoreLets bnds body'-    return $ case comp of-                GT -> mkCoreApps body'' $ drop lenvs args-                _  -> body''---- | A more powerful 'inline'. Matches two cases:---      Var ==> inlines---      App ==> inlines the head of the function call for the app tree-unfoldR :: forall c. (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-unfoldR = go >>> cleanupUnfoldR-    where go :: Rewrite c HermitM CoreExpr-          go = inline <+ appAllR go idR--unfoldPredR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => (Id -> [CoreExpr] -> Bool) -> Rewrite c HermitM CoreExpr-unfoldPredR p = callPredT p >>= \ _ -> unfoldR--unfoldNameR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => TH.Name -> Rewrite c HermitM CoreExpr-unfoldNameR nm = callNameT nm >>= \ _ -> unfoldR--unfoldAnyR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => [TH.Name] -> Rewrite c HermitM CoreExpr-unfoldAnyR = orR . map unfoldNameR--unfoldSaturatedR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-unfoldSaturatedR = callSaturatedT >>= \ _ -> unfoldR--specializeR :: (ExtendPath c Crumb, AddBindings c, ReadBindings c) => Rewrite c HermitM CoreExpr-specializeR = unfoldPredR (const (all isTyCoArg))---- NOTE: Using a Rewrite because of the way the Kernel is set up.---       This is a temporary hack until we work out the best way to structure the Kernel.---- | Stash a binding with a name for later use.--- Allows us to look at past definitions.-rememberR :: Label -> Rewrite c HermitM Core-rememberR label = sideEffectR $ \ _ -> \case-                                          DefCore def           -> saveDef label def-                                          BindCore (NonRec i e) -> saveDef label (Def i e)-                                          _                     -> fail "remember: not a binding"---- | Stash a binding with a name for later use.--- Allows us to look at past definitions.--- rememberR :: String -> Translate c m Core ()--- rememberR label = contextfreeT $ \ core ->---     case core of---         DefCore def -> saveDef label def---         BindCore (NonRec i e) -> saveDef label (Def i e)---         _           -> fail "remember: not a binding"---- | Apply a stashed definition (like inline, but looks in stash instead of context).-unfoldStashR :: ReadBindings c => String -> Rewrite c HermitM CoreExpr-unfoldStashR label = setFailMsg "Inlining stashed definition failed: " $-                     withPatFailMsg (wrongExprForm "Var v") $-    do (c, Var v) <- exposeT-       constT $ do Def i rhs <- lookupDef label-                   if idName i == idName v -- TODO: Is there a reason we're not just using equality on Id?-                   then ifM ((all (inScope c) . toList) <$> apply freeVarsT c rhs)-                            (return rhs)-                            (fail "some free variables in stashed definition are no longer in scope.")-                   else fail $ "stashed definition applies to " ++ var2String i ++ " not " ++ var2String v--showStashT :: Injection CoreDef a => PrettyH a -> Translate c HermitM a DocH-showStashT pp = do-    stash <- constT getStash-    docs <- forM (Map.toList stash) $ \ (l,d) -> do-                dfn <- constT $ apply (extractT pp) initPrettyC d-                return $ PP.text ("[ " ++ l ++ " ]") PP.$+$ dfn PP.$+$ PP.space-    return $ PP.vcat docs
− src/Language/HERMIT/Shell/Command.hs
@@ -1,813 +0,0 @@-{-# LANGUAGE FlexibleInstances, FlexibleContexts, ScopedTypeVariables, GADTs, TypeFamilies, DeriveDataTypeable #-}--module Language.HERMIT.Shell.Command-       ( -- * The HERMIT Command-line Shell-         commandLine-       , unicodeConsole-) where--import qualified GhcPlugins as GHC--import Control.Applicative-import Control.Arrow hiding (loop)-import Control.Concurrent-import Control.Concurrent.STM-import Control.Exception.Base hiding (catch)-import Control.Monad.State-import Control.Monad.Error--import Data.Char-import Data.Monoid-import Data.List (intercalate, isPrefixOf, nub)-import Data.Default (def)-import Data.Dynamic-import qualified Data.Map as M-import Data.Maybe--import Language.HERMIT.Context-import Language.HERMIT.Monad-import Language.HERMIT.Kure-import Language.HERMIT.Dictionary-import Language.HERMIT.External-import Language.HERMIT.Interp-import Language.HERMIT.Kernel (queryK)-import Language.HERMIT.Kernel.Scoped-import Language.HERMIT.Parser-import Language.HERMIT.PrettyPrinter.Common--import Language.HERMIT.Primitive.GHC-import Language.HERMIT.Primitive.Inline-import Language.HERMIT.Primitive.Navigation--import System.Console.ANSI-import System.IO--import qualified Text.PrettyPrint.MarkedHughesPJ as PP--import System.Console.Haskeline hiding (catch)---- There are 4 types of commands, AST effect-ful, Shell effect-ful, Queries, and Meta-commands.--data ShellCommand =  AstEffect   AstEffect-                  |  ShellEffect ShellEffect-                  |  QueryFun    QueryFun-                  |  MetaCommand MetaCommand---- GADTs can't have docs on constructors. See Haddock ticket #43.--- | AstEffects are things that are recorded in our log and saved files.---   - Apply a rewrite (giving a whole new lower-level AST).---   - Change the current location using a computed path.---   - Change the currect location using directions.---   - Begin or end a scope.---   - Add a tag.---   - Run a precondition or other predicate that must not fail.-data AstEffect :: * where-   Apply      :: (Injection GHC.ModGuts g, Walker HermitC g) => RewriteH g              -> AstEffect-   Pathfinder :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g PathH      -> AstEffect-   Direction  ::                                                Direction               -> AstEffect---   PushFocus Path -- This changes the current location using a give path-   BeginScope ::                                                                           AstEffect-   EndScope   ::                                                                           AstEffect-   Tag        :: String                                                                 -> AstEffect-   CorrectnessCritera :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g () -> AstEffect-   deriving Typeable--instance Extern AstEffect where-   type Box AstEffect = AstEffect-   box i = i-   unbox i = i--data ShellEffect :: * where-   SessionStateEffect    :: (CommandLineState -> SessionState -> IO SessionState) -> ShellEffect-   deriving Typeable--data QueryFun :: * where-   QueryString   :: (Injection GHC.ModGuts g, Walker HermitC g) => TranslateH g String                             -> QueryFun-   QueryDocH     ::                                                (PrettyH CoreTC -> TranslateH CoreTC DocH)      -> QueryFun-   -- These two be can generalized into-   --  (CommandLineState -> IO String)-   Display       ::                                                                                                   QueryFun-   Message       ::                                                String                                          -> QueryFun-   Inquiry       ::                                                (CommandLineState -> SessionState -> IO String) -> QueryFun-   deriving Typeable--instance Extern QueryFun where-   type Box QueryFun = QueryFun-   box i = i-   unbox i = i--data MetaCommand-   = Resume-   | Abort-   | Dump String String String Int-   | LoadFile String  -- load a file on top of the current node-   | SaveFile String-   | Delete SAST-   deriving Typeable--instance Extern MetaCommand where-    type Box MetaCommand = MetaCommand-    box i = i-    unbox i = i---- TODO: Use another word, Navigation is a more general concept--- Perhaps VersionNavigation-data Navigation = Back                  -- back (up) the derivation tree-                | Step                  -- down one step; assumes only one choice-                | Goto Int              -- goto a specific node, if possible-                | GotoTag String        -- goto a specific named tag-        deriving Show--data ShellCommandBox = ShellCommandBox ShellCommand deriving Typeable--instance Extern ShellEffect where-    type Box ShellEffect = ShellEffect-    box i = i-    unbox i = i--instance Extern ShellCommand where-    type Box ShellCommand = ShellCommandBox-    box = ShellCommandBox-    unbox (ShellCommandBox i) = i--interpShellCommand :: [Interp ShellCommand]-interpShellCommand =-  [ interp $ \ (ShellCommandBox cmd)         -> cmd-  , interp $ \ (RewriteCoreBox rr)           -> AstEffect (Apply rr)-  , interp $ \ (RewriteCoreTCBox rr)         -> AstEffect (Apply rr)-  , interp $ \ (BiRewriteCoreBox br)         -> AstEffect (Apply $ forewardT br)-  , interp $ \ (CrumbBox cr)                 -> AstEffect (Pathfinder (return [cr] :: TranslateH CoreTC PathH))-  , interp $ \ (PathBox p)                   -> AstEffect (Pathfinder (return p :: TranslateH CoreTC PathH))-  , interp $ \ (TranslateCorePathBox tt)     -> AstEffect (Pathfinder tt)-  , interp $ \ (StringBox str)               -> QueryFun (Message str)-  , interp $ \ (TranslateCoreStringBox tt)   -> QueryFun (QueryString tt)-  , interp $ \ (TranslateCoreTCStringBox tt) -> QueryFun (QueryString tt)-  , interp $ \ (TranslateCoreTCDocHBox tt)   -> QueryFun (QueryDocH $ unTranslateDocH tt)-  , interp $ \ (TranslateCoreCheckBox tt)    -> AstEffect (CorrectnessCritera tt)-  , interp $ \ (effect :: AstEffect)         -> AstEffect effect-  , interp $ \ (effect :: ShellEffect)       -> ShellEffect effect-  , interp $ \ (query :: QueryFun)           -> QueryFun query-  , interp $ \ (meta :: MetaCommand)         -> MetaCommand meta-  ]--- TODO: move this into the shell, it is completely specific to the way--- the shell works. What about list, for example?----interpKernelCommand :: [Interp KernelCommand]---interpKernelCommand =---             [ Interp $ \ (KernelCommandBox cmd)      -> cmd---             ]--shell_externals :: [External]-shell_externals = map (.+ Shell)-   [-     external "resume"          Resume    -- HERMIT Kernel Exit-       [ "stops HERMIT; resumes compile" ]-   , external "abort"           Abort     -- UNIX Exit-       [ "hard UNIX-style exit; does not return to GHC; does not save" ]-   , external "gc"              (Delete . SAST)-       [ "garbage-collect a given AST; does not remove from command log" ]-   , external "gc"              (SessionStateEffect gc)-       [ "garbage-collect all ASTs except for the initial and current AST" ]-   , external "display"         Display-       [ "redisplays current state" ]-   , external "left"            (Direction L)-       [ "move to the next child"]-   , external "right"           (Direction R)-       [ "move to the previous child"]-   , external "up"              (Direction U)-       [ "move to the parent node"]-   , external "down"            (deprecatedIntToPathT 0 :: TranslateH Core PathH) -- TODO: short-term solution-       [ "move to the first child"]-   , external "tag"             Tag-       [ "tag <label> names the current AST with a label" ]-   , external "navigate"        (SessionStateEffect $ \ _ st -> return $ st { cl_nav = True })-       [ "switch to navigate mode" ]-   , external "command-line"    (SessionStateEffect $ \ _ st -> return $ st { cl_nav = False })-       [ "switch to command line mode" ]-   , external "top"             (Direction T)-       [ "move to root of current scope" ]-   , external "back"            (SessionStateEffect $ navigation Back)-       [ "go back in the derivation" ]                                          .+ VersionControl-   , external "log"             (Inquiry showDerivationTree)-       [ "go back in the derivation" ]                                          .+ VersionControl-   , external "step"            (SessionStateEffect $ navigation Step)-       [ "step forward in the derivation" ]                                     .+ VersionControl-   , external "goto"            (SessionStateEffect . navigation . Goto)-       [ "goto a specific step in the derivation" ]                             .+ VersionControl-   , external "goto"            (SessionStateEffect . navigation . GotoTag)-       [ "goto a named step in the derivation" ]-   , external "set-fail-hard" (\ bStr -> SessionStateEffect $ \ _ st ->-        case reads bStr of-            [(b,"")] -> return $ st { cl_failhard = b }-            _        -> return st )-       [ "set-fail-hard <True|False>; False by default"-       , "any rewrite failure causes compilation to abort" ]-   , external "set-auto-corelint" (\ bStr -> SessionStateEffect $ \ _ st ->-        case reads bStr of-            [(b,"")] -> return $ st { cl_corelint = b }-            _        -> return st )-       [ "set-auto-corelint <True|False>; False by default"-       , "run core lint type-checker after every rewrite, reverting on failure" ]-   , external "set-pp"           (\ pp -> SessionStateEffect $ \ _ st ->-       case M.lookup pp pp_dictionary of-         Nothing -> do-            putStrLn $ "List of Pretty Printers: " ++ intercalate ", " (M.keys pp_dictionary)-            return st-         Just _ -> return $ st { cl_pretty = pp })-       [ "set the pretty printer"-       , "use 'set-pp ls' to list available pretty printers" ]-   , external "set-pp-renderer"    changeRenderer-       [ "set the output renderer mode"]-   , external "set-pp-renderer"    showRenderers-       [ "set the output renderer mode"]-   , external "dump"    Dump-       [ "dump <filename> <pretty-printer> <renderer> <width>"]-   , external "set-pp-width"   (\ n -> SessionStateEffect $ \ _ st -> return $ st { cl_width = n })-       ["set the width of the screen"]-   , external "set-pp-type" (\ str -> SessionStateEffect $ \ _ st ->-        case reads str :: [(ShowOption,String)] of-            [(opt,"")] -> return $ st { cl_pretty_opts = updateTypeShowOption opt (cl_pretty_opts st) }-            _          -> return st)-       ["set how to show expression-level types (Show|Abstact|Omit)"]-   , external "set-pp-coercion" (\ str -> SessionStateEffect $ \ _ st ->-        case reads str :: [(ShowOption,String)] of-            [(opt,"")] -> return $ st { cl_pretty_opts = updateCoShowOption opt (cl_pretty_opts st) }-            _          -> return st)-       ["set how to show coercions (Show|Abstact|Omit)"]-   , external "{"   BeginScope-       ["push current lens onto a stack"]       -- tag as internal-   , external "}"   EndScope-       ["pop a lens off a stack"]               -- tag as internal-   , external "load"  LoadFile-       ["load <filename> : load a file of commands into the current derivation"]-   , external "save"  SaveFile-       ["save <filename> : save the current complete derivation into a file"]-   ]--showRenderers :: QueryFun-showRenderers = Message $ "set-renderer " ++ show (map fst finalRenders)--changeRenderer :: String -> ShellEffect-changeRenderer renderer = SessionStateEffect $ \ _ st ->-        case lookup renderer finalRenders of-          Nothing -> return st          -- TODO: should fail with message-          Just r  -> return $ st { cl_render = r }--gc :: CommandLineState -> SessionState -> IO SessionState-gc clst st = do-    let k = cl_kernel clst-        cursor = cl_cursor st-        initSAST = cl_initSAST clst-    asts <- listS k-    mapM_ (deleteS k) [ sast | sast <- asts, sast `notElem` [cursor, initSAST] ]-    return st--------------------------------------------------------------------------------------catch :: IO a -> (String -> IO a) -> IO a-catch = catchJust (\ (err :: IOException) -> return (show err))--pretty :: SessionState -> PrettyH CoreTC-pretty ss = case M.lookup (cl_pretty ss) pp_dictionary of-                Just pp -> pp (cl_pretty_opts ss)-                Nothing -> pure (PP.text $ "<<no pretty printer for " ++ cl_pretty ss ++ ">>")--showFocus :: MonadIO m => CLM m ()-showFocus = do-    st <- get-    -- No not show focus while loading-    ifM (gets (cl_loading . cl_session))-        (return ())-        (iokm2clm' "Rendering error: "-                   (liftIO . cl_render (cl_session st) stdout (cl_pretty_opts $ cl_session st))-                   (queryS (cl_kernel st) (cl_cursor $ cl_session st) (liftPrettyH $ pretty $ cl_session st) (cl_kernel_env $ cl_session st))-        )-----------------------------------------------------------------------------------type CLM m a = ErrorT String (StateT CommandLineState m) a---- TODO: Come up with names for these, and/or better characterise these abstractions.-iokm2clm' :: MonadIO m => String -> (a -> CLM m b) -> IO (KureM a) -> CLM m b-iokm2clm' msg ret m = liftIO m >>= runKureM ret (throwError . (msg ++))--iokm2clm :: MonadIO m => String -> IO (KureM a) -> CLM m a-iokm2clm msg = iokm2clm' msg return--iokm2clm'' :: MonadIO m => IO (KureM a) -> CLM m a-iokm2clm'' = iokm2clm ""--data CommandLineState = CommandLineState-        { cl_graph       :: [(SAST,ExprH,SAST)]-        , cl_tags        :: [(String,SAST)]-        -- these three should be in a reader-        , cl_dict        :: Dictionary-        , cl_kernel      :: ScopedKernel-        , cl_initSAST    :: SAST-        -- and the session state (perhaps in a seperate state?)-        , cl_session     :: SessionState-        }--newSAST :: ExprH -> SAST -> CommandLineState -> CommandLineState-newSAST expr sast st = st { cl_session = (cl_session st) { cl_cursor = sast }-                          , cl_graph = (cl_cursor (cl_session st), expr, sast) : cl_graph st-                          }---- Session-local issues; things that are never saved.-data SessionState = SessionState-        { cl_cursor      :: SAST                                     -- ^ the current AST-        , cl_pretty      :: String                                   -- ^ which pretty printer to use-        , cl_pretty_opts :: PrettyOptions                            -- ^ The options for the pretty printer-        , cl_render      :: Handle -> PrettyOptions -> DocH -> IO () -- ^ the way of outputing to the screen-        , cl_width       :: Int                                      -- ^ how wide is the screen?-        , cl_nav         :: Bool                                     -- ^ keyboard input the the nav panel-        , cl_loading     :: Bool                                     -- ^ if loading a file-        , cl_tick        :: TVar (M.Map String Int)                  -- ^ The list of ticked messages-        , cl_corelint    :: Bool                                     -- ^ if true, run core lint on module after each rewrite-        , cl_failhard    :: Bool                                     -- ^ if true, abort on *any* failure-        }-----------------------------------------------------------------------------------data CompletionType = ConsiderC -- complete with possible arguments to consider-                    | InlineC   -- complete with names that can be inlined-                    | CommandC  -- complete using dictionary commands (default)-                    | AmbiguousC [CompletionType]  -- completionType function needs to be more specific-    deriving (Show)---- TODO: reverse rPrev and parse it, to better figure out what possiblities are in context?---       for instance, completing "any-bu (inline " should be different than completing just "inline "---       this would also allow typed completion?-completionType :: String -> CompletionType-completionType = go . dropWhile isSpace-    where go rPrev = case [ ty | (nm, ty) <- opts, reverse nm `isPrefixOf` rPrev ] of-                        []  -> CommandC-                        [t] -> t-                        ts  -> AmbiguousC ts-          opts = [ ("inline"  , InlineC  )-                 , ("consider", ConsiderC)-                 , ("rhs-of"  , ConsiderC)-                 ]---- TODO: For the moment, we promote the translations on Core to translations on CoreTC.  But we should probably update considerTargets and inlineTargets.-completionQuery :: CommandLineState -> CompletionType -> IO (TranslateH CoreTC [String])-completionQuery _ ConsiderC = return $ promoteT considerTargets >>^ ((++ map fst considerables) . map ('\'':))-completionQuery _ InlineC   = return $ promoteT inlineTargets   >>^ map ('\'':)-completionQuery s CommandC  = return $ pure (M.keys (cl_dict s))--- Need to modify opts in completionType function. No key can be a suffix of another key.-completionQuery _ (AmbiguousC ts) = do-    putStrLn "\nCannot tab complete: ambiguous completion type."-    putStrLn $ "Possibilities: " ++ intercalate ", " (map show ts)-    return (pure [])--shellComplete :: MVar CommandLineState -> String -> String -> IO [Completion]-shellComplete mvar rPrev so_far = do-    st <- readMVar mvar-    targetQuery <- completionQuery st (completionType rPrev)-    -- (liftM.liftM) (map simpleCompletion . nub . filter (so_far `isPrefixOf`))-    --     $ queryS (cl_kernel st) (cl_cursor (cl_session st)) targetQuery-    -- TODO: I expect you want to build a silent version of the kernal_env for this query-    mcls <- queryS (cl_kernel st) (cl_cursor $ cl_session st) targetQuery (cl_kernel_env $ cl_session st)-    cl <- runKureM return (\ _ -> return []) mcls-    return $ (map simpleCompletion . nub . filter (so_far `isPrefixOf`)) cl--setLoading :: MonadIO m => Bool -> CLM m ()-setLoading b = modify $ \st -> st { cl_session = (cl_session st) { cl_loading = b } }--banner :: String-banner = unlines-    [ "===================== Welcome to HERMIT ====================="-    , "HERMIT is a toolkit for the interactive transformation of GHC"-    , "core language programs. Documentation on HERMIT can be found"-    , "on the HERMIT web page at:"-    , "http://www.ittc.ku.edu/csdl/fpg/software/hermit.html"-    , ""-    , "You have just loaded the interactive shell. To exit, type "-    , "\"abort\" or \"resume\" to abort or resume GHC compilation."-    , ""-    , "Type \"help\" for instructions on how to list or search the"-    , "available HERMIT commands."-    , ""-    , "To get started, you could try the following:"-    , "  - type \"consider 'foo\", where \"foo\" is a function"-    , "    defined in the module;"-    , "  - type \"set-pp-type Show\" to switch on typing information;"-    , "  - use natural numbers such as \"0\" and \"1\" to descend into"-    , "    the definition, and \"up\" to ascend;"-    , "  - type \"info\" for more information about the current node;"-    , "  - type \"log\" to display an activity log."-    , "============================================================="-    ]---- | The first argument is a list of files to load.-commandLine :: [FilePath] -> Behavior -> [External] -> ScopedKernel -> SAST -> IO ()-commandLine filesToLoad behavior exts skernel sast = do-    let dict = mkDict $ shell_externals ++ exts-    let ws_complete = " ()"--    let startup = do-            liftIO $ putStrLn banner-            setLoading True-            sequence_ [ performMetaCommand $ case fileName of-                         "abort"  -> Abort-                         "resume" -> Resume-                         _        -> LoadFile fileName-                      | fileName <- reverse filesToLoad-                      , not (null fileName)-                      ] `ourCatch` \ msg -> liftIO . putStrLn $ "Booting Failure: " ++ msg-            setLoading False--    var <- GHC.liftIO $ atomically $ newTVar M.empty--    let sessionState = SessionState sast "clean" def unicodeConsole 80 False False var False False-        shellState = CommandLineState [] [] dict skernel sast sessionState--    completionMVar <- newMVar shellState--    _ <- runInputTBehavior behavior-                (setComplete (completeWordWithPrev Nothing ws_complete (shellComplete completionMVar)) defaultSettings)-                (evalStateT (runErrorT (startup >> showFocus >> loop completionMVar)) shellState)--    return ()--loop :: (MonadIO m, m ~ InputT IO) => MVar CommandLineState -> CLM m ()-loop completionMVar = loop'-  where loop' = do-            st <- get-            -- so the completion can get the current state-            liftIO $ modifyMVar_ completionMVar (const $ return st)-            -- liftIO $ print (cl_pretty st, cl_cursor (cl_session st))-            let SAST n = cl_cursor (cl_session st)-            maybeLine <- if cl_nav (cl_session st)-                           then liftIO getNavCmd-                           else lift $ lift $ getInputLine $ "hermit<" ++ show n ++ "> "--            case maybeLine of-                Nothing             -> performMetaCommand Resume-                Just ('-':'-':_msg) -> loop'-                Just line           ->-                    if all isSpace line-                    then loop'-                    else (case parseStmtsH line of-                                Left  msg   -> throwError ("Parse failure: " ++ msg)-                                Right stmts -> evalStmts stmts)-                         `ourCatch` (liftIO . putStrLn)-                           >> loop'--ourCatch :: MonadIO m => CLM IO () -> (String -> CLM m ()) -> CLM m ()-ourCatch m failure = do-    st <- get-    (res,st') <- liftIO $ runStateT (runErrorT m) st-    put st'-    case res of-        Left msg -> if cl_failhard (cl_session st')-                    then do-                        performQuery Display-                        liftIO $ putStrLn msg >> abortS (cl_kernel st')-                    else failure msg-        Right () -> return ()--evalStmts :: MonadIO m => [ExprH] -> CLM m ()-evalStmts = mapM_ evalExpr--evalExpr :: MonadIO m => ExprH -> CLM m ()-evalExpr expr = do-    dict <- gets cl_dict-    case interpExprH dict interpShellCommand expr of-      Left msg  -> throwError msg-      Right cmd -> case cmd of-                     AstEffect effect   -> performAstEffect effect expr-                     ShellEffect effect -> performShellEffect effect-                     QueryFun query     -> performQuery query-                     MetaCommand meta   -> performMetaCommand meta------------------------------------------------------------------------------------- TODO: This can be refactored. We always showFocus. Also, Perhaps return a modifier, not ()---   UPDATE: Not true.  We don't always showFocus.--- TODO: All of these should through an exception if they fail to execute the command as given.--performAstEffect :: MonadIO m => AstEffect -> ExprH -> CLM m ()-performAstEffect (Apply rr) expr = do-    st <- get--    let sk = cl_kernel st-        kEnv = cl_kernel_env $ cl_session st--    sast' <- iokm2clm "Rewrite failed: " $ applyS sk (cl_cursor $ cl_session st) rr kEnv--    let commit = put (newSAST expr sast' st) >> showFocus--    if cl_corelint (cl_session st)-        then do ast' <- iokm2clm'' $ toASTS sk sast'-                liftIO (queryK (kernelS sk) ast' lintModuleT kEnv)-                >>= runKureM (\ warns -> putStrToConsole warns >> commit)-                             (\ errs  -> liftIO (deleteS sk sast') >> fail errs)-        else commit--performAstEffect (Pathfinder t) expr = do-    st <- get-    -- An extension to the Path-    iokm2clm' "Cannot find path: "-              (\ p -> do ast <- iokm2clm "Path is invalid: " $ modPathS (cl_kernel st) (cl_cursor (cl_session st)) (extendLocalPath p) (cl_kernel_env $ cl_session st)-                         put $ newSAST expr ast st-                         showFocus)-              (queryS (cl_kernel st) (cl_cursor $ cl_session st) t (cl_kernel_env $ cl_session st))--performAstEffect (Direction dir) expr = do-    st <- get-    ast <- iokm2clm "Invalid move: " $ modPathS (cl_kernel st) (cl_cursor $ cl_session st) (moveLocally dir) (cl_kernel_env $ cl_session st)-    put $ newSAST expr ast st-    -- something changed, to print-    showFocus--performAstEffect BeginScope expr = do-        st <- get-        ast <- iokm2clm'' $ beginScopeS (cl_kernel st) (cl_cursor (cl_session st))-        put $ newSAST expr ast st-        showFocus--performAstEffect EndScope expr = do-        st <- get-        ast <- iokm2clm'' $ endScopeS (cl_kernel st) (cl_cursor (cl_session st))-        put $ newSAST expr ast st-        showFocus--performAstEffect (Tag tag) _ = do-        st <- get-        put (st { cl_tags = (tag, cl_cursor $ cl_session st) : cl_tags st })--performAstEffect (CorrectnessCritera q) expr = do-        st <- get-        -- TODO: Again, we may want a quiet version of the kernel_env-        liftIO (queryS (cl_kernel st) (cl_cursor $ cl_session st) q (cl_kernel_env $ cl_session st))-          >>= runKureM (\ () -> putStrToConsole $ unparseExprH expr ++ " [correct]")-                       (\ err -> fail $ unparseExprH expr ++ " [exception: " ++ err ++ "]")-----------------------------------------------------------------------------------performShellEffect :: MonadIO m => ShellEffect -> CLM m ()-performShellEffect (SessionStateEffect f) = do-        st <- get-        opt <- liftIO (fmap Right (f st $ cl_session st) `catch` \ str -> return (Left str))-        case opt of-          Right s_st' -> do put (st { cl_session = s_st' })-                            showFocus-          Left err -> throwError err-----------------------------------------------------------------------------------performQuery :: MonadIO m => QueryFun -> CLM m ()-performQuery (QueryString q) = do-    st <- get-    iokm2clm' "Query failed: "-              putStrToConsole-              (queryS (cl_kernel st) (cl_cursor $ cl_session st) q (cl_kernel_env $ cl_session st))--performQuery (QueryDocH q) = do-    st <- get-    let ss = cl_session st-    iokm2clm' "Query failed: "-              (liftIO . cl_render ss stdout (cl_pretty_opts ss))-              (queryS (cl_kernel st) (cl_cursor ss) (q $ pretty ss) (cl_kernel_env ss))--performQuery (Inquiry f) = do-    st <- get-    str <- liftIO $ f st (cl_session st)-    putStrToConsole str---- These two need to use Inquiry-performQuery (Message msg) = liftIO (putStrLn msg)--- Explicit calls to display should work no matter what the loading state is.-performQuery Display = do-    load_st <- gets (cl_loading . cl_session)-    setLoading False-    showFocus-    setLoading load_st-----------------------------------------------------------------------------------performMetaCommand :: MonadIO m => MetaCommand -> CLM m ()-performMetaCommand Abort  = gets cl_kernel >>= (liftIO . abortS)-performMetaCommand Resume = do st <- get-                               iokm2clm'' $ resumeS (cl_kernel st) (cl_cursor $ cl_session st)-performMetaCommand (Delete sast) = gets cl_kernel >>= iokm2clm'' . flip deleteS sast-performMetaCommand (Dump fileName _pp renderer width) = do-    st <- get-    case (M.lookup (cl_pretty (cl_session st)) pp_dictionary,lookup renderer finalRenders) of-      (Just pp, Just r) -> do doc <- iokm2clm "Bad pretty-printer or renderer option: " $-                                         queryS (cl_kernel st) (cl_cursor $ cl_session st) (liftPrettyH $ pp (cl_pretty_opts $ cl_session st)) (cl_kernel_env $ cl_session st)-                              liftIO $ do h <- openFile fileName WriteMode-                                          r h ((cl_pretty_opts $ cl_session st) { po_width = width }) doc-                                          hClose h-      _ -> throwError "dump: bad pretty-printer or renderer option"-performMetaCommand (LoadFile fileName) = do-        putStrToConsole $ "[loading " ++ fileName ++ "]"-        res <- liftIO $ try (readFile fileName)-        case res of-          Right str -> case parseStmtsH str of-                        Left  msg  -> throwError ("Parse failure: " ++ msg)-                        Right stmts -> do-                            load_st <- gets (cl_loading . cl_session)-                            setLoading True-                            evalStmts stmts `catchError` (\ err -> do-                                    setLoading load_st-                                    throwError err)-                            setLoading load_st-                            putStrToConsole $ "[done, loaded " ++ show (numStmtsH stmts) ++  " commands]" -- TODO: This is better than saying "N", but not very robust.-                            showFocus-          Left (err :: IOException) -> throwError ("IO error: " ++ show err)--performMetaCommand (SaveFile fileName) = do-        st <- get-        putStrToConsole $ "[saving " ++ fileName ++ "]"-        -- no checks to see if you are clobering; be careful-        liftIO $ writeFile fileName $ showGraph (cl_graph st) (cl_tags st) (SAST 0)------------------------------------------------------------------------------------putStrToConsole :: MonadIO m => String -> CLM m ()-putStrToConsole str = ifM (gets (cl_loading . cl_session))-                          (return ())-                          (liftIO $ putStrLn str)-----------------------------------------------------------------------------------newtype UnicodeTerminal = UnicodeTerminal (Handle -> Maybe PathH -> IO ())--instance RenderSpecial UnicodeTerminal where-        renderSpecial sym = UnicodeTerminal $ \ h _ -> hPutStr h [ch]-                where (Unicode ch) = renderSpecial sym--instance Monoid UnicodeTerminal where-        mempty = UnicodeTerminal $ \ _ _ -> return ()-        mappend (UnicodeTerminal f1) (UnicodeTerminal f2) = UnicodeTerminal $ \ h p -> f1 h p >> f2 h p--finalRenders :: [(String,Handle -> PrettyOptions -> DocH -> IO ())]-finalRenders =-        [ ("unicode-terminal", unicodeConsole)-        ] ++ coreRenders--unicodeConsole :: Handle -> PrettyOptions -> DocH -> IO ()-unicodeConsole h w doc = do-    let (UnicodeTerminal prty) = renderCode w doc-    prty h Nothing---instance RenderCode UnicodeTerminal where-        rPutStr txt  = UnicodeTerminal $ \ h _ -> hPutStr h txt--        rDoHighlight _ [] = UnicodeTerminal $ \ h _ -> hSetSGR h [Reset]-        rDoHighlight _ (Color col:_) = UnicodeTerminal $ \ h _ -> do-                hSetSGR h [ Reset ]-                hSetSGR h $ case col of-                        KeywordColor  -> [ SetConsoleIntensity BoldIntensity-                                         , SetColor Foreground Dull Blue-                                         ]-                        SyntaxColor   -> [ SetColor Foreground Dull Red ]-                        IdColor       -> []   -- as is-                        CoercionColor -> [ SetColor Foreground Dull Yellow ]-                        TypeColor     -> [ SetColor Foreground Dull Green ]-                        LitColor      -> [ SetColor Foreground Dull Cyan ]-                        WarningColor  -> [ SetSwapForegroundBackground True, SetColor Foreground Vivid Yellow ]-        rDoHighlight o (_:rest) = rDoHighlight o rest-        rEnd = UnicodeTerminal $ \ h _ -> hPutStrLn h ""------------------------------------------------------------navigation :: Navigation -> CommandLineState -> SessionState -> IO SessionState-navigation whereTo st sess_st =-    case whereTo of-      Goto n -> do-           all_nds <- listS (cl_kernel st)-           if SAST n `elem` all_nds-              then return $ sess_st { cl_cursor = SAST n }-              else fail $ "Cannot find AST #" ++ show n ++ "."-      GotoTag tag -> case lookup tag (cl_tags st) of-                       Just sast -> return $ sess_st { cl_cursor = sast }-                       Nothing   -> fail $ "Cannot find tag " ++ show tag ++ "."-      Step -> do-           let ns = [ edge | edge@(s,_,_) <- cl_graph st, s == cl_cursor (cl_session st) ]-           case ns of-             [] -> fail "Cannot step forward (no more steps)."-             [(_,cmd,d) ] -> do-                           putStrLn $ "step : " ++ unparseExprH cmd-                           return $ sess_st { cl_cursor = d }-             _ -> fail "Cannot step forward (multiple choices)"-      Back -> do-           let ns = [ edge | edge@(_,_,d) <- cl_graph st, d == cl_cursor (cl_session st) ]-           case ns of-             []         -> fail "Cannot step backwards (no more steps)."-             [(s,cmd,_) ] -> do-                           putStrLn $ "back, unstepping : " ++ unparseExprH cmd-                           return $ sess_st { cl_cursor = s }-             _          -> fail "Cannot step backwards (multiple choices, impossible!)."------------------------------------------------------------getNavCmd :: IO (Maybe String)-getNavCmd = do-        b_in <- hGetBuffering stdin-        hSetBuffering stdin NoBuffering-        b_out <- hGetBuffering stdin-        hSetBuffering stdout NoBuffering-        ec_in <- hGetEcho stdin-        hSetEcho stdin False-        putStr "(navigation mode; use arrow keys, escape to quit, '?' for help)"-        r <- readCh []-        putStr "\n"-        hSetBuffering stdin b_in-        hSetBuffering stdout b_out-        hSetEcho stdin ec_in-        return r-  where-   readCh xs = do-        x <- getChar-        let str = xs ++ [x]-        (fromMaybe reset $ lookup str cmds) str--   reset _ = do-        putStr "\BEL"-        readCh []--   res str _ = return (Just str)--   cmds = [ ("\ESC" , \ str -> ifM (hReady stdin)-                                   (readCh str)-                                   (return $ Just "command-line"))-          , ("\ESC[" , readCh)-          , ("\ESC[A", res "up")-          , ("\ESC[B", res "down")-          , ("\ESC[C", res "right")-          , ("\ESC[D", res "left")-          , ("?",      res "nav-commands")-          , ("f",      res "step")-          ] ++-          [ (show n, res (show n)) | n <- [0..9] :: [Int] ]---showDerivationTree :: CommandLineState -> SessionState -> IO String-showDerivationTree st ss = return $ unlines $ showRefactorTrail graph tags 0 me-  where-          graph = [ (a,[unparseExprH b],c) | (SAST a,b,SAST c) <- cl_graph st ]-          tags  = [ (n,nm) | (nm,SAST n) <- cl_tags st ]-          SAST me = cl_cursor ss--showRefactorTrail :: (Eq a, Show a) => [(a,[String],a)] -> [(a,String)] -> a -> a -> [String]-showRefactorTrail db tags a me =-        case [ (b,c) | (a0,b,c) <- db, a == a0 ] of-           [] -> [show' 3 a ++ " " ++ dot ++ tags_txt]-           ((b,c):bs) ->-                      [show' 3 a ++ " " ++ dot ++ (if not (null bs) then "->" else "") ++ tags_txt ] ++-                      ["    " ++ "| " ++ txt | txt <- b ] ++-                      showRefactorTrail db tags c me ++-                      if null bs-                      then []-                      else [] :-                          showRefactorTrail [ (a',b',c') | (a',b',c') <- db-                                                          , not (a == a' && c == c')-                                                          ]  tags a me--  where-          dot = if a == me then "*" else "o"-          show' n x = replicate (n - length (show a)) ' ' ++ show x-          tags_txt = concat [ ' ' : txt-                            | (n,txt) <- tags-                            , n == a-                            ]---showGraph :: [(SAST,ExprH,SAST)] -> [(String,SAST)] -> SAST -> String-showGraph graph tags this@(SAST n) =-        (if length paths > 1 then "tag " ++ show n ++ "\n" else "") ++-        concat (intercalate-                ["goto " ++ show n ++ "\n"]-                [ [ unparseExprH b ++ "\n" ++ showGraph graph tags c ]-                | (b,c) <- paths-                ])-  where-          paths = [ (b,c) | (a,b,c) <- graph, a == this ]--------------------------------------------------------------------------------------------------cl_kernel_env  :: SessionState -> HermitMEnv-cl_kernel_env ss = mkHermitMEnv $ \ msg -> case msg of-                DebugTick    msg'      -> do-                        c <- GHC.liftIO $ tick (cl_tick ss) msg'-                        GHC.liftIO $ putStrLn $ "<" ++ show c ++ "> " ++ msg'-                DebugCore  msg' cxt core -> do-                        GHC.liftIO $ putStrLn $ "[" ++ msg' ++ "]"-                        doc :: DocH <- apply (pretty ss) (liftPrettyC cxt) (inject core)-                        GHC.liftIO $ cl_render ss stdout (cl_pretty_opts ss) doc---- tick counter-tick :: TVar (M.Map String Int) -> String -> IO Int-tick var msg = atomically $ do-        m <- readTVar var-        let c = case M.lookup msg m of-                Nothing -> 1-                Just x  -> x + 1-        writeTVar var (M.insert msg c m)-        return c-
− src/Language/HERMIT/Syntax.hs
@@ -1,55 +0,0 @@-module Language.HERMIT.Syntax-   (-      -- * Utility Predicates for lexing Identifiers-      -- ** Lexing HERMIT Scripts-      isScriptIdFirstChar,-      isScriptIdChar,-      isScriptInfixIdChar,-      -- ** Lexing Core Fragments-      isCoreIdFirstChar,-      isCoreIdChar,-      isCoreInfixIdChar-   )-where--import Data.Char (isAlphaNum, isAlpha)--------------------------------------------------------------------------- | Characters that are valid as the leading character of an identifier in a HERMIT script.-isScriptIdFirstChar :: Char -> Bool-isScriptIdFirstChar c = isAlphaNum c || c `elem` "$_:."---- | Characters that are valid identifier elements (a superset of 'isScriptIdFirstChar') in a HERMIT script.-isScriptIdChar :: Char -> Bool-isScriptIdChar c = isScriptIdFirstChar c || c `elem` "-'"---- | Characters that are valid in infix operators in a HERMIT script.-isScriptInfixIdChar :: Char -> Bool-isScriptInfixIdChar c = c `elem` infixOperatorSymbols-                        -- old: "!£$%^&*-+=@#<>?/.:|"--------------------------------------------------------------------------- | Chars that are valid as the leading character of an identifier in a Core fragment.-isCoreIdFirstChar :: Char -> Bool-isCoreIdFirstChar c = c `elem` "_$[]:.=" || isAlpha c---- | Characters that are valid identifier elements (a superset of 'isCoreIdFirstChar') in a Core fragment.-isCoreIdChar :: Char -> Bool-isCoreIdChar c = isAlphaNum c || c `elem` "#-'" || isCoreIdFirstChar c---- | Characters that are valid in infix operators in a Core fragment.-isCoreInfixIdChar :: Char -> Bool-isCoreInfixIdChar c = c `elem` infixOperatorSymbols-                      -- old: "+*/._-:<>"--------------------------------------------------------------------------- TODO: Should the set of infix operator symobls be common to both HERMIT scripts and Core fragments?---       I'm pretty sure the old definition of isCoreInfixIdChar was too limited at least.--infixOperatorSymbols :: [Char]-infixOperatorSymbols = "!£$%^&*-+=@#<>?/.:|"-----------------------------------------------------------------------