h-raylib-5.6.0.0: src/Raylib/Internal/TH.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE TupleSections #-}
-- | Template Haskell functions used internally
module Raylib.Internal.TH (genNative) where
#ifdef WEB_FFI
import Language.Haskell.TH
( Body (NormalB),
Clause (Clause),
Dec (FunD, SigD),
DecsQ,
Exp (AppE, LitE, VarE),
Lit (StringL),
TypeQ,
mkName,
)
import Raylib.Internal.Web.Native (callRaylibFunction)
#else
import Language.Haskell.TH
( Dec (ForeignD),
DecsQ,
TypeQ,
mkName, Foreign (ImportF), Callconv (CCall), Safety (Safe),
)
#endif
-- | Generates native code for the given functions. On non-web platforms, this
-- means @foreign import@ statements. On web platforms, this means
-- `callRaylibFunction` calls.
genNative ::
-- | (@hsName@, @cName@, @cFile@, @funType@)
[(String, String, String, TypeQ)] ->
DecsQ
genNative funs = do
funs' <- mapM (\(a, b, c, d) -> (a,b,c,) <$> d) funs
return (genNative' funs')
where
genNative' [] = []
#ifdef WEB_FFI
genNative' ((hsName, cName, _, funType) : xs) =
[ -- hsName :: funType
SigD name funType,
-- hsName = callRaylibFunction "_cName"
FunD
name
[Clause [] (NormalB (AppE (VarE 'callRaylibFunction) (LitE (StringL ('_' : cName))))) []]
] ++ genNative' xs
where
name = mkName hsName
#else
genNative' ((hsName, cName, cFile, funType) : xs) =
-- foreign import ccall safe/unsafe "cFile cName" hsName :: funType
ForeignD (ImportF CCall Safe (cFile ++ " " ++ cName) (mkName hsName) funType) : genNative' xs
#endif