module Language.HERMIT.Context
(
HermitC
, initHermitC
, (@@)
, addAltBindings
, addBinding
, addCaseBinding
, addLambdaBinding
, hermitBindings
, hermitDepth
, hermitPath
, hermitModGuts
, lookupHermitBinding
, boundVars
, boundIn
, findBoundVars
, HermitBinding(..)
, hermitBindingDepth
) where
import Prelude hiding (lookup)
import GhcPlugins hiding (empty)
import Data.Map hiding (map, foldr, filter)
import qualified Language.Haskell.TH as TH
import Language.HERMIT.GHC
import Language.KURE
data HermitBinding
= BIND Int Bool CoreExpr
| LAM Int
| CASE Int CoreExpr (AltCon,[Id])
hermitBindingDepth :: HermitBinding -> Int
hermitBindingDepth (LAM d) = d
hermitBindingDepth (BIND d _ _) = d
hermitBindingDepth (CASE d _ _) = d
data HermitC = HermitC
{ hermitBindings :: Map Var HermitBinding
, hermitDepth :: Int
, hermitPath :: AbsolutePath
, hermitModGuts :: ModGuts
}
instance PathContext HermitC where
contextPath :: HermitC -> AbsolutePath
contextPath = hermitPath
initHermitC :: ModGuts -> HermitC
initHermitC modGuts = HermitC empty 0 rootAbsPath modGuts
(@@) :: HermitC -> Int -> HermitC
(@@) c v = c { hermitPath = extendAbsPath v (hermitPath c) }
addBinding :: CoreBind -> HermitC -> HermitC
addBinding corebind c = let nextDepth = succ (hermitDepth c)
hbds = hermitBindings c
newBds = case corebind of
NonRec v e -> insert v (BIND nextDepth False e) hbds
Rec bds -> hbds `union` fromList [ (b, BIND nextDepth True e) | (b,e) <- bds ]
in c { hermitBindings = newBds
, hermitDepth = nextDepth
}
addCaseBinding :: (Id,CoreExpr,CoreAlt) -> HermitC -> HermitC
addCaseBinding (v,e,(con,vs,_)) c = let nextDepth = succ (hermitDepth c)
in c { hermitBindings = insert v (CASE nextDepth e (con,vs)) (hermitBindings c)
, hermitDepth = nextDepth
}
addLambdaBinding :: Var -> HermitC -> HermitC
addLambdaBinding v c = let nextDepth = succ (hermitDepth c)
in c { hermitBindings = insert v (LAM nextDepth) (hermitBindings c)
, hermitDepth = nextDepth
}
addAltBindings :: [Id] -> HermitC -> HermitC
addAltBindings vs c = let nextDepth = succ (hermitDepth c)
in c { hermitBindings = foldr (\ v bds -> insert v (LAM nextDepth) bds) (hermitBindings c) vs
, hermitDepth = nextDepth
}
lookupHermitBinding :: Var -> HermitC -> Maybe HermitBinding
lookupHermitBinding n env = lookup n (hermitBindings env)
boundVars :: HermitC -> [Var]
boundVars = keys . hermitBindings
boundIn :: Var -> HermitC -> Bool
boundIn i c = i `elem` boundVars c
findBoundVars :: TH.Name -> HermitC -> [Var]
findBoundVars nm = filter (cmpTHName2Var nm) . boundVars