module Language.HERMIT.Primitive.Common
(
progVarsT
, bindVarsT
, nonRecVarT
, recVarsT
, defVarT
, lamVarT
, letVarsT
, letRecVarsT
, letNonRecVarT
, caseVarsT
, caseWildVarT
, caseAltVarsT
, altVarsT
, boundVarsT
, findBoundVarT
, findIdT
, wrongExprForm
)
where
import GhcPlugins
import Data.List
import Data.Monoid
import Language.HERMIT.Kure
import Language.HERMIT.Core
import Language.HERMIT.Context
import Language.HERMIT.GHC
import qualified Language.Haskell.TH as TH
progVarsT :: TranslateH CoreProg [Id]
progVarsT = progNilT [] <+ progConsT bindVarsT progVarsT (++)
bindVarsT :: TranslateH CoreBind [Var]
bindVarsT = fmap return nonRecVarT <+ recVarsT
nonRecVarT :: TranslateH CoreBind Var
nonRecVarT = nonRecT mempty (\ v () -> v)
recVarsT :: TranslateH CoreBind [Id]
recVarsT = recT (\ _ -> defVarT) id
defVarT :: TranslateH CoreDef Id
defVarT = defT mempty (\ v () -> v)
lamVarT :: TranslateH CoreExpr Var
lamVarT = lamT mempty (\ v () -> v)
letVarsT :: TranslateH CoreExpr [Var]
letVarsT = letT bindVarsT mempty (\ vs () -> vs)
letRecVarsT :: TranslateH CoreExpr [Var]
letRecVarsT = letT recVarsT mempty (\ vs () -> vs)
letNonRecVarT :: TranslateH CoreExpr Var
letNonRecVarT = letT nonRecVarT mempty (\ v () -> v)
caseVarsT :: TranslateH CoreExpr [Var]
caseVarsT = caseT mempty (\ _ -> altVarsT) (\ () v _ vss -> v : nub (concat vss))
caseWildVarT :: TranslateH CoreExpr Var
caseWildVarT = caseT mempty (\ _ -> return ()) (\ () v _ _ -> v)
caseAltVarsT :: TranslateH CoreExpr [[Var]]
caseAltVarsT = caseT mempty (\ _ -> altVarsT) (\ () _ _ vss -> vss)
altVarsT :: TranslateH CoreAlt [Var]
altVarsT = altT mempty (\ _ vs () -> vs)
boundVarsT :: TranslateH a [Var]
boundVarsT = contextonlyT (return . boundVars)
findBoundVarT :: TH.Name -> TranslateH a Var
findBoundVarT nm = prefixFailMsg ("Cannot resolve name " ++ TH.nameBase nm ++ ", ") $
do c <- contextT
case findBoundVars nm c of
[] -> fail "no matching variables in scope."
[v] -> return v
_ : _ : _ -> fail "multiple matching variables in scope."
findIdT :: TH.Name -> TranslateH a Id
findIdT nm = prefixFailMsg ("Cannot resolve name " ++ TH.nameBase nm ++ ", ") $
do c <- contextT
case findBoundVars nm c of
[] -> findIdMG nm
[v] -> return v
_ : _ : _ -> fail "multiple matching variables in scope."
findIdMG :: TH.Name -> TranslateH a Id
findIdMG nm = contextonlyT $ \ c ->
case filter isValName $ findNameFromTH (mg_rdr_env $ hermitModGuts c) nm of
[] -> fail $ "variable not in scope."
[n] -> lookupId n
ns -> do dynFlags <- getDynFlags
fail $ "multiple matches found:\n" ++ intercalate ", " (map (showPpr dynFlags) ns)
wrongExprForm :: String -> String
wrongExprForm form = "Expression does not have the form: " ++ form