{-# OPTIONS_GHC -optc-DUSE_RINTERNALS #-}
{-# LINE 1 "src/Foreign/R/Internal.hsc" #-}
{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LINE 14 "src/Foreign/R/Internal.hsc" #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LINE 23 "src/Foreign/R/Internal.hsc" #-}
{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}
{-# LINE 26 "src/Foreign/R/Internal.hsc" #-}
module Foreign.R.Internal where
import Control.Memory.Region
import {-# SOURCE #-} Language.R.HExp (HExp)
import Foreign.R.Type
import Foreign.R.Type as R
import Foreign.R.Context (SEXP0)
import Control.Applicative
import Control.DeepSeq (NFData(..))
import Control.Monad.Primitive ( unsafeInlineIO )
import Data.Singletons (fromSing)
{-# LINE 41 "src/Foreign/R/Internal.hsc" #-}
import Foreign (Ptr, castPtr, plusPtr, Storable(..))
import Foreign.C
import Prelude hiding (asTypeOf, length)
newtype SEXP s (a :: SEXPTYPE) = SEXP { unSEXP :: Ptr (HExp s a) }
deriving ( Eq
, Ord
, Storable
{-# LINE 64 "src/Foreign/R/Internal.hsc" #-}
)
instance Show (SEXP s a) where
show (SEXP ptr) = show ptr
instance NFData (SEXP s a) where
rnf = (`seq` ())
sexp :: SEXP0 -> SEXP s a
sexp = SEXP . castPtr
unsexp :: SEXP s a -> SEXP0
unsexp = castPtr . unSEXP
somesexp :: SEXP0 -> SomeSEXP s
somesexp = SomeSEXP . sexp
release :: (t <= s) => SEXP s a -> SEXP t a
release = unsafeRelease
unsafeRelease :: SEXP s a -> SEXP r a
unsafeRelease = sexp . unsexp
data SomeSEXP s = forall a. SomeSEXP {-# UNPACK #-} !(SEXP s a)
instance Show (SomeSEXP s) where
show s = unSomeSEXP s show
instance Storable (SomeSEXP s) where
sizeOf _ = sizeOf (undefined :: SEXP s a)
alignment _ = alignment (undefined :: SEXP s a)
peek ptr = SomeSEXP <$> peek (castPtr ptr)
poke ptr (SomeSEXP s) = poke (castPtr ptr) s
instance NFData (SomeSEXP s) where
rnf = (`seq` ())
unSomeSEXP :: SomeSEXP s -> (forall a. SEXP s a -> r) -> r
unSomeSEXP (SomeSEXP s) k = k s
cIntConv :: (Integral a, Integral b) => a -> b
cIntConv = fromIntegral
cIntToEnum :: Enum a => CInt -> a
cIntToEnum = toEnum . cIntConv
cUIntFromSingEnum :: SSEXPTYPE a -> CUInt
cUIntFromSingEnum = cIntConv . fromEnum . fromSing
cIntFromEnum :: Enum a => a -> CInt
cIntFromEnum = cIntConv . fromEnum
typeOf :: SEXP s a -> SEXPTYPE
typeOf s = unsafeInlineIO $ cIntToEnum <$> cTYPEOF (unsexp s)
foreign import capi unsafe "TYPEOF" cTYPEOF :: SEXP0 -> IO CInt
setCar :: SEXP s a -> SEXP s b -> IO ()
setCar s s' = (\hsc_ptr -> pokeByteOff hsc_ptr 32) (unsexp s) (castPtr $ unsexp s')
{-# LINE 140 "src/Foreign/R/Internal.hsc" #-}
setCdr :: SEXP s a -> SEXP s b -> IO ()
setCdr s s' = (\hsc_ptr -> pokeByteOff hsc_ptr 40) (unsexp s) (castPtr $ unsexp s')
{-# LINE 144 "src/Foreign/R/Internal.hsc" #-}
setTag :: SEXP s a -> SEXP s b -> IO ()
setTag s s' = (\hsc_ptr -> pokeByteOff hsc_ptr 48) (unsexp s) (castPtr $ unsexp s')
{-# LINE 148 "src/Foreign/R/Internal.hsc" #-}
unsafeCast :: SEXPTYPE -> SomeSEXP s -> SEXP s b
unsafeCast ty (SomeSEXP s)
| ty == typeOf s = unsafeCoerce s
| otherwise =
error $ "cast: Dynamic type cast failed. Expected: " ++ show ty ++
". Actual: " ++ show (typeOf s) ++ "."
cast :: SSEXPTYPE a -> SomeSEXP s -> SEXP s a
cast ty s = unsafeCast (fromSing ty) s
asTypeOf :: SomeSEXP s -> SEXP s a -> SEXP s a
asTypeOf s s' = typeOf s' `unsafeCast` s
unsafeCoerce :: SEXP s a -> SEXP s b
unsafeCoerce = sexp . castPtr . unsexp
length :: R.IsVector a => SEXP s a -> IO Int
length s = fromIntegral <$>
((\hsc_ptr -> peekByteOff hsc_ptr 32) (unsexp s) :: IO CInt)
{-# LINE 193 "src/Foreign/R/Internal.hsc" #-}
unsafeSEXPToVectorPtr :: SEXP s a -> Ptr ()
unsafeSEXPToVectorPtr s = (unsexp s) `plusPtr` (40)
{-# LINE 197 "src/Foreign/R/Internal.hsc" #-}
unsafeVectorPtrToSEXP :: Ptr a -> SomeSEXP s
unsafeVectorPtrToSEXP s = SomeSEXP $ sexp $ s `plusPtr` (- (40))
{-# LINE 201 "src/Foreign/R/Internal.hsc" #-}
foreign import ccall "&R_Interactive" isRInteractive :: Ptr CInt
foreign import ccall "&R_NilValue" nilValue :: Ptr (SEXP G R.Nil)
foreign import ccall "&R_UnboundValue" unboundValue :: Ptr (SEXP G R.Symbol)
foreign import ccall "&R_MissingArg" missingArg :: Ptr (SEXP G R.Symbol)
foreign import ccall "&R_BaseEnv" baseEnv :: Ptr (SEXP G R.Env)
foreign import ccall "&R_EmptyEnv" emptyEnv :: Ptr (SEXP G R.Env)
foreign import ccall "&R_GlobalEnv" globalEnv :: Ptr (SEXP G R.Env)
foreign import ccall "&R_SignalHandlers" signalHandlers :: Ptr CInt
foreign import ccall "&R_interrupts_pending" interruptsPending :: Ptr CInt
data SEXPInfo = SEXPInfo
{ infoType :: SEXPTYPE
, infoObj :: Bool
, infoNamed :: Int
, infoGp :: Int
, infoMark :: Bool
, infoDebug :: Bool
, infoTrace :: Bool
, infoSpare :: Bool
, infoGcGen :: Int
, infoGcCls :: Int
} deriving ( Show )
peekInfo :: SEXP s a -> IO SEXPInfo
peekInfo ts =
SEXPInfo
<$> (toEnum.fromIntegral <$> cTYPEOF s)
<*> ((/=0) <$> cOBJECT s)
<*> (fromIntegral <$> cNAMED s)
<*> (fromIntegral <$> cLEVELS s)
<*> ((/=0) <$> cMARK s)
<*> ((/=0) <$> cRDEBUG s)
<*> ((/=0) <$> cRTRACE s)
<*> ((/=0) <$> cRSTEP s)
<*> (fromIntegral <$> cGCGEN s)
<*> (fromIntegral <$> cGCCLS s)
where
s = unsexp ts
foreign import capi unsafe "OBJECT" cOBJECT :: SEXP0 -> IO CInt
foreign import capi unsafe "NAMED" cNAMED :: SEXP0 -> IO CInt
foreign import capi unsafe "LEVELS" cLEVELS :: SEXP0 -> IO CInt
foreign import capi unsafe "MARK" cMARK :: SEXP0 -> IO CInt
foreign import capi unsafe "RDEBUG" cRDEBUG :: SEXP0 -> IO CInt
foreign import capi unsafe "RTRACE" cRTRACE :: SEXP0 -> IO CInt
foreign import capi unsafe "RSTEP" cRSTEP :: SEXP0 -> IO CInt
foreign import capi unsafe "missing_r.h GCGEN" cGCGEN :: SEXP0 -> IO CInt
foreign import capi unsafe "missing_r.h GCCLS" cGCCLS :: SEXP0 -> IO CInt
pokeInfo :: SEXP s a -> SEXPInfo -> IO ()
pokeInfo (unsexp -> s) i = do
cSET_TYPEOF s (fromIntegral.fromEnum $ infoType i)
cSET_OBJECT s (if infoObj i then 1 else 0)
cSET_NAMED s (fromIntegral $ infoNamed i)
cSETLEVELS s (fromIntegral $ infoGp i)
cSET_MARK s (if infoMark i then 1 else 0)
cSET_RDEBUG s (if infoDebug i then 1 else 0)
cSET_RTRACE s (if infoTrace i then 1 else 0)
cSET_RSTEP s (if infoSpare i then 1 else 0)
cSET_GCGEN s (fromIntegral $ infoGcGen i)
cSET_GCCLS s (fromIntegral $ infoGcCls i)
foreign import capi unsafe "SET_TYPEOF" cSET_TYPEOF :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SET_OBJECT" cSET_OBJECT :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SET_NAMED" cSET_NAMED :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SETLEVELS" cSETLEVELS :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SET_MARK" cSET_MARK :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SET_RDEBUG" cSET_RDEBUG :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SET_RTRACE" cSET_RTRACE :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "SET_RSTEP" cSET_RSTEP :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "missing_r.h SET_GCGEN" cSET_GCGEN :: SEXP0 -> CInt -> IO ()
foreign import capi unsafe "missing_r.h SET_GCCLS" cSET_GCCLS :: SEXP0 -> CInt -> IO ()
mark :: Bool -> SEXP s a -> IO ()
mark b ts = cSET_MARK (unsexp ts) (if b then 1 else 0)
named :: Int -> SEXP s a -> IO ()
named v ts = cSET_NAMED (unsexp ts) (fromIntegral v)
isS4 :: SEXP s ty -> Bool
isS4 s = (>0) $ cisS4 (unsexp s)
getAttributes :: SEXP s a -> IO (SEXP s b)
getAttributes s = sexp <$> cAttrib (unsexp s)
getAttribute :: SEXP s a
-> SEXP s2 b
-> SEXP s c
getAttribute a b = sexp $ cgetAttrib (unsexp a) (unsexp b)
setAttributes :: SEXP s a -> SEXP s b -> IO ()
setAttributes s v = csetAttrib (unsexp s) (castPtr $ unsexp v)
foreign import capi unsafe "Rinternals.h ATTRIB" cAttrib :: SEXP0 -> IO SEXP0
foreign import capi unsafe "Rinternals.h SET_ATTRIB" csetAttrib :: SEXP0 -> SEXP0 -> IO ()
foreign import capi unsafe "Rinternals.h Rf_getAttrib" cgetAttrib :: SEXP0 -> SEXP0 -> SEXP0
foreign import capi unsafe "Rinternals.h Rf_isS4" cisS4 :: SEXP0 -> Int