{-# LANGUAGE TypeFamilies #-}
module LLVM.Extra.Function (
C,
CodeGen,
define,
create,
createNamed,
Return, Result, ret,
) where
import qualified LLVM.Util.Proxy as LP
import qualified LLVM.Core as LLVM
import Foreign.StablePtr (StablePtr)
import Foreign.Ptr (Ptr, FunPtr)
import Control.Applicative ((<*>))
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Word (Word8, Word16, Word32, Word64, Word)
define ::
(C f) => LLVM.Function f -> CodeGen f -> LLVM.CodeGenModule ()
define fn body =
LLVM.defineFunction fn (addRet (proxyFromElement2 fn) body)
proxyFromElement2 :: f (g a) -> LP.Proxy a
proxyFromElement2 _ = LP.Proxy
create ::
(C f) =>
LLVM.Linkage -> CodeGen f -> LLVM.CodeGenModule (LLVM.Function f)
create linkage body = do
f <- LLVM.newFunction linkage
define f body
return f
createNamed ::
(C f) =>
LLVM.Linkage -> String -> CodeGen f -> LLVM.CodeGenModule (LLVM.Function f)
createNamed linkage name body = do
f <- LLVM.newNamedFunction linkage name
define f body
return f
class LLVM.FunctionArgs f => C f where
type CodeGen f
addRet :: LP.Proxy f -> CodeGen f -> LLVM.FunctionCodeGen f
instance (C b, LLVM.IsFirstClass a) => C (a -> b) where
type CodeGen (a -> b) = LLVM.Value a -> CodeGen b
addRet proxy f a = addRet (proxy<*>LP.Proxy) (f a)
instance Return a => C (IO a) where
type CodeGen (IO a) = LLVM.CodeGenFunction a (Result a)
addRet LP.Proxy code = code >>= ret
class (LLVM.IsFirstClass a) => Return a where
type Result a
ret :: Result a -> LLVM.CodeGenFunction a ()
instance Return () where
type Result () = ()
ret = LLVM.ret
instance Return Bool where
type Result Bool = LLVM.Value Bool; ret = LLVM.ret
instance Return Int where
type Result Int = LLVM.Value Int; ret = LLVM.ret
instance Return Int8 where
type Result Int8 = LLVM.Value Int8; ret = LLVM.ret
instance Return Int16 where
type Result Int16 = LLVM.Value Int16; ret = LLVM.ret
instance Return Int32 where
type Result Int32 = LLVM.Value Int32; ret = LLVM.ret
instance Return Int64 where
type Result Int64 = LLVM.Value Int64; ret = LLVM.ret
instance Return Word where
type Result Word = LLVM.Value Word; ret = LLVM.ret
instance Return Word8 where
type Result Word8 = LLVM.Value Word8; ret = LLVM.ret
instance Return Word16 where
type Result Word16 = LLVM.Value Word16; ret = LLVM.ret
instance Return Word32 where
type Result Word32 = LLVM.Value Word32; ret = LLVM.ret
instance Return Word64 where
type Result Word64 = LLVM.Value Word64; ret = LLVM.ret
instance Return Float where
type Result Float = LLVM.Value Float; ret = LLVM.ret
instance Return Double where
type Result Double = LLVM.Value Double; ret = LLVM.ret
instance Return (Ptr a) where
type Result (Ptr a) = LLVM.Value (Ptr a); ret = LLVM.ret
instance (LLVM.IsType a) => Return (LLVM.Ptr a) where
type Result (LLVM.Ptr a) = LLVM.Value (LLVM.Ptr a); ret = LLVM.ret
instance (LLVM.IsFunction a) => Return (FunPtr a) where
type Result (FunPtr a) = LLVM.Value (FunPtr a); ret = LLVM.ret
instance Return (StablePtr a) where
type Result (StablePtr a) = LLVM.Value (StablePtr a); ret = LLVM.ret