module System.Linux.Ptrace.GenStruct where
import Control.Monad
import Foreign
import Language.Haskell.TH
genStruct :: String -> [String] -> Q Type -> Q [Dec]
genStruct name ctors elemType = do
let name' = mkName name
elemType' <- elemType
varsAndTypes <- mapM (\n -> varStrictType (mkName n) (strictType notStrict elemType)) ctors
let typeDecl = DataD [] name' [] [RecC name' varsAndTypes] [''Show]
let elemSize = [|sizeOf (undefined :: $(elemType))|]
let fixDecs :: Q [Dec] -> Q [DecQ]
fixDecs decs = (fmap.fmap) return decs
let numCtors = length ctors
storableInst <- instanceD (cxt []) (appT (conT ''Storable) (conT name')) =<<
fixDecs [d|
sizeOf _ = numCtors * $(elemSize)
alignment _ = alignment (undefined :: $(elemType))
peek p = $(foldl (\e k -> [| $e `ap` peekByteOff p (k * $(elemSize)) |]) [|return $(conE name')|] [0..length ctors1])
poke p v = sequence_ $(listE $ map (\(n,c) -> [| pokeByteOff p (n * $(elemSize)) ($(varE (mkName c)) v) |]) $ zip [0::Int ..] ctors)
|]
return [typeDecl, storableInst]