hoop-0.3.0.0: src/Language/MSH/CodeGen/Methods.hs
--------------------------------------------------------------------------------
-- Monadic State Hierarchies --
-- Copyright 2013-2019 Michael B. Gale (m.gale@warwick.ac.uk) --
--------------------------------------------------------------------------------
module Language.MSH.CodeGen.Methods (
genMethods
) where
--------------------------------------------------------------------------------
import qualified Data.Map as M
import Debug.Trace
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Language.MSH.StateDecl
import Language.MSH.StateEnv
import Language.MSH.MethodTable
import Language.MSH.CodeGen.Shared
import Language.MSH.CodeGen.Inheritance
--------------------------------------------------------------------------------
genMethodBody :: Name -> Dec -> Dec
genMethodBody name (ValD (VarP _) body wh) = ValD (VarP name) body wh
genMethodBody name (FunD _ cs) = FunD name cs
genMethod' :: String -> String -> [String] -> Type -> Dec -> Q [Dec]
genMethod' className name vars ty def = do
o <- newName "o"
s <- newName "s"
m <- newName "m"
let
n' = mkName $ "_" ++ className ++ "_" ++ name
svs = appN (VarT s) vars
stt = AppT (AppT (ConT (mkName "StateT")) svs) (VarT m)
tvs = [PlainTV o, PlainTV s, PlainTV m] ++ [PlainTV (mkName v) | v <- vars]
cxt = [foldl AppT (ConT $ mkName $ className ++ "Like") ([VarT o, VarT s, VarT m] ++ map (VarT . mkName) vars)]
return [
SigD n' $ unwrapForalls ty $ ForallT tvs cxt $ wrapMethodType False (\rt -> AppT stt rt) ty
, genMethodBody n' def
]
-- | Generates a method belonging to a state class.
genMethod :: StateDecl -> String -> [String] -> (String, MethodEntry) -> Q [Dec]
genMethod decl n vars (name, entry)
| abstractEntry entry = trace (name ++ " is abstract in " ++ show decl) $ return []
| otherwise = case entry of
GenesisMethod _ (Just (SigD _ ty)) (Just def) ->
genMethod' n name vars ty def
OverridenMethod (SigD _ ty) def ->
genMethod' n name vars ty def
InheritedMethod _ (SigD _ ty) (Just def) ->
genMethod' n name vars ty def
_ -> error $ "[genMethod] Unexpected method table entry:\n " ++ show entry
-- genMethod env decl n vars (ValD (VarP name) body wh) = do
-- let
-- n' = mkName $ "_" ++ n ++ "_" ++ nameBase name
-- return [ValD (VarP n') body wh]
-- genMethod env decl n vars (FunD name cs) = do
-- let
-- n' = mkName $ "_" ++ n ++ "_" ++ nameBase name
-- return [FunD n' cs]
-- genMethod env decl n vars dec = fail $
-- "Unsupported type of definition within a state class:\n" ++ show dec
-- | Generates methods for a state class.
-- genMethods :: StateEnv -> StateDecl -> String -> [String] -> [Dec] -> Q [Dec]
-- genMethods env decl n vars ds = do
-- concat `fmap` mapM (genMethod env decl n vars) ds
-- | `genMethods` Generates methods for a state class.
genMethods :: StateDecl -> String -> [String] -> Q [Dec]
genMethods decl n vars =
concat <$> mapM (genMethod decl n vars) ms
where ms = M.toList $ methods $ stateMethods decl
--------------------------------------------------------------------------------