{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MagicHash #-}
module Language.Haskell.TH.Lift
( Lift(..)
, Q
, Code
, Quote
, Exp
, defaultLiftTyped
, liftAddrCompat
, liftIntCompat
) where
import GHC.Exts (Int(..))
import Data.Word (Word8)
#if __GLASGOW_HASKELL__ < 810
import Foreign.Ptr (plusPtr)
import Foreign.Storable (peek)
import Foreign.ForeignPtr (withForeignPtr)
import System.IO.Unsafe (unsafePerformIO)
#endif
import Foreign.ForeignPtr (ForeignPtr)
#if __GLASGOW_HASKELL__ >= 912
import GHC.Internal.TH.Lift
import GHC.Internal.TH.Syntax
#else
import Language.Haskell.TH.Syntax
#endif
#if __GLASGOW_HASKELL__ >= 915
import GHC.Internal.TH.Monad
#endif
#if __GLASGOW_HASKELL__ < 900
type Quote m = (Q ~ m)
type Code m a = m (TExp a)
#endif
#if __GLASGOW_HASKELL__ >= 900
defaultLiftTyped :: (Lift a, Quote m) => a -> Code m a
defaultLiftTyped :: forall a (m :: * -> *). (Lift a, Quote m) => a -> Code m a
defaultLiftTyped a
x = m Exp -> Code m a
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (a -> m Exp
forall t (m :: * -> *). (Lift t, Quote m) => t -> m Exp
forall (m :: * -> *). Quote m => a -> m Exp
lift a
x)
#else
defaultLiftTyped :: (Lift a, Quote m) => a -> Q (TExp a)
defaultLiftTyped x = unsafeTExpCoerce (lift x)
#endif
liftAddrCompat :: Quote m => ForeignPtr Word8 -> Word -> Word -> m Exp
liftAddrCompat :: forall (m :: * -> *).
Quote m =>
ForeignPtr Word8 -> Word -> Word -> m Exp
liftAddrCompat ForeignPtr Word8
fptr Word
off Word
len =
#if __GLASGOW_HASKELL__ >= 810
Exp -> m Exp
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Exp -> m Exp) -> Exp -> m Exp
forall a b. (a -> b) -> a -> b
$ Lit -> Exp
LitE (Lit -> Exp) -> Lit -> Exp
forall a b. (a -> b) -> a -> b
$ Bytes -> Lit
BytesPrimL (Bytes -> Lit) -> Bytes -> Lit
forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Word -> Word -> Bytes
Bytes ForeignPtr Word8
fptr Word
off Word
len
#else
do
let
loop !ptr 0 xs = pure $ reverse xs
loop !ptr !len xs = do
x <- peek ptr
loop (ptr `plusPtr` 1) (len -1) (x:xs)
let words = unsafePerformIO $ withForeignPtr fptr $ \ptr -> loop (ptr `plusPtr` (fromIntegral off)) len []
pure $ LitE $ StringPrimL $ words
#endif
liftIntCompat :: Quote m => Integer -> m Exp
liftIntCompat :: forall (m :: * -> *). Quote m => Integer -> m Exp
liftIntCompat Integer
n = Exp -> m Exp
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Exp -> m Exp) -> Exp -> m Exp
forall a b. (a -> b) -> a -> b
$ Exp -> Exp -> Exp
AppE (Name -> Exp
ConE 'I#) (Lit -> Exp
LitE (Integer -> Lit
IntPrimL Integer
n))