{-# LANGUAGE DataKinds #-}
{-# Language ViewPatterns #-}

module Language.R.Internal
  ( r1
  , r2
  , installIO
  ) where

import           Control.Memory.Region
import qualified Foreign.R as R
import           Language.R

import Data.ByteString as B
import Foreign.C.String ( withCString )

inVoid :: R V z -> R V z
inVoid :: forall z. R V z -> R V z
inVoid = forall a. a -> a
id
{-# INLINE inVoid #-}

-- | Call a pure unary R function of the given name in the global environment.
r1 :: ByteString -> SEXP s a -> IO (SomeSEXP V)
r1 :: forall s (a :: SEXPTYPE). ByteString -> SEXP s a -> IO (SomeSEXP V)
r1 ByteString
fn SEXP s a
a =
    forall a. ByteString -> (CString -> IO a) -> IO a
useAsCString ByteString
fn forall a b. (a -> b) -> a -> b
$ \CString
cfn -> CString -> IO (SEXP V 'Symbol)
R.install CString
cfn forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SEXP V 'Symbol
f ->
      forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (forall s (a :: SEXPTYPE) (b :: SEXPTYPE).
SEXP s a -> SEXP s b -> IO (SEXP V 'Lang)
R.lang2 SEXP V 'Symbol
f (forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s a
a)) (forall a s. NFData a => R s a -> IO a
unsafeRunRegion forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall z. R V z -> R V z
inVoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) s (a :: SEXPTYPE).
MonadR m =>
SEXP s a -> m (SomeSEXP (Region m))
eval)

-- | Call a pure binary R function. See 'r1' for additional comments.
r2 :: ByteString -> SEXP s a -> SEXP s b -> IO (SomeSEXP V)
r2 :: forall s (a :: SEXPTYPE) (b :: SEXPTYPE).
ByteString -> SEXP s a -> SEXP s b -> IO (SomeSEXP V)
r2 ByteString
fn SEXP s a
a SEXP s b
b =
    forall a. ByteString -> (CString -> IO a) -> IO a
useAsCString ByteString
fn forall a b. (a -> b) -> a -> b
$ \CString
cfn -> CString -> IO (SEXP V 'Symbol)
R.install CString
cfn forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SEXP V 'Symbol
f ->
      forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (forall s (a :: SEXPTYPE) (b :: SEXPTYPE) (c :: SEXPTYPE).
SEXP s a -> SEXP s b -> SEXP s c -> IO (SEXP V 'Lang)
R.lang3 SEXP V 'Symbol
f (forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s a
a) (forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s b
b)) (forall a s. NFData a => R s a -> IO a
unsafeRunRegion forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall z. R V z -> R V z
inVoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) s (a :: SEXPTYPE).
MonadR m =>
SEXP s a -> m (SomeSEXP (Region m))
eval)

-- | Internalize a symbol name.
installIO :: String -> IO (SEXP V 'R.Symbol)
installIO :: String -> IO (SEXP V 'Symbol)
installIO String
str = forall a. String -> (CString -> IO a) -> IO a
withCString String
str CString -> IO (SEXP V 'Symbol)
R.install