-- |
-- Copyright: 2013 (C) Amgen, Inc
--
-- Wrappers for low-level R functions.

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

module Language.R
  ( module Foreign.R
  , module Foreign.R.Type
  , module Language.R.Instance
  , module Language.R.Globals
  , module Language.R.GC
  , module Language.R.Literal
  -- * Evaluation
  , eval
  , eval_
  , evalEnv
  , install
  , cancel
  -- * Exceptions
  , throwR
  , throwRMessage
  -- * Deprecated
  , parseFile
  , parseText
  , string
  , strings
  ) where

import           Control.Memory.Region
import qualified Data.Vector.SEXP as Vector
import Control.Monad.R.Class
import Foreign.R
  ( SEXP
  , SomeSEXP(..)
  , typeOf
  , asTypeOf
  , cast
  , unSomeSEXP
  , unsafeCoerce
  )
import qualified Foreign.R as R
import qualified Foreign.R.Parse as R
import qualified Foreign.R.Error as R
import           Foreign.R.Type
import           Language.R.GC
import           Language.R.Globals
import           Language.R.HExp
import           Language.R.Instance
import           {-# SOURCE #-} Language.R.Internal
import           Language.R.Literal

import Control.Applicative
import Control.Exception ( throwIO )
import Control.Monad ( (>=>), when, unless, forM, void )
import Data.ByteString as B
import Data.ByteString.Char8 as C8 ( pack, unpack )
import Data.Singletons (sing)
import Foreign
  ( alloca
  , castPtr
  , peek
  , poke
  )
import Foreign.C.String ( withCString, peekCString )
import Prelude

-- NOTE: In this module, cannot use quasiquotations, since we are lower down in
-- the dependency hierarchy.

-- | Parse and then evaluate expression.
parseEval :: ByteString -> IO (SomeSEXP V)
parseEval :: ByteString -> IO (SomeSEXP V)
parseEval txt :: ByteString
txt = ByteString -> (CString -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a. ByteString -> (CString -> IO a) -> IO a
useAsCString ByteString
txt ((CString -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (CString -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \ctxt :: CString
ctxt ->
  IO (SEXP V 'String)
-> (SEXP V 'String -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (CString -> IO (SEXP V 'String)
R.mkString CString
ctxt) ((SEXP V 'String -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (SEXP V 'String -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \rtxt :: SEXP V 'String
rtxt ->
    (Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \status :: Ptr CInt
status -> do
      IO (SEXP V 'Expr)
-> (SEXP Any 'Expr -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (SEXP V 'String
-> Int -> Ptr CInt -> SEXP V 'Nil -> IO (SEXP V 'Expr)
forall (a :: SEXPTYPE) s.
In a '[ 'Nil, 'String] =>
SEXP s 'String -> Int -> Ptr CInt -> SEXP s a -> IO (SEXP s 'Expr)
R.parseVector SEXP V 'String
rtxt 1 Ptr CInt
status (SEXP G 'Nil -> SEXP V 'Nil
forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP G 'Nil
nilValue)) ((SEXP Any 'Expr -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (SEXP Any 'Expr -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \exprs :: SEXP Any 'Expr
exprs -> do
        Int
rc <- CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
status
        Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ParseStatus
R.PARSE_OK ParseStatus -> ParseStatus -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> ParseStatus
forall a. Enum a => Int -> a
toEnum Int
rc) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
          (forall s. R s ()) -> IO ()
forall a. NFData a => (forall s. R s a) -> IO a
runRegion ((forall s. R s ()) -> IO ()) -> (forall s. R s ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> R s ()
forall (m :: * -> *) a. MonadR m => String -> m a
throwRMessage (String -> R s ()) -> String -> R s ()
forall a b. (a -> b) -> a -> b
$ "Parse error in: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ByteString -> String
C8.unpack ByteString
txt
        SomeSEXP expr :: SEXP Any a
expr <- Ptr (SomeSEXP Any) -> IO (SomeSEXP Any)
forall a. Storable a => Ptr a -> IO a
peek (Ptr (SomeSEXP Any) -> IO (SomeSEXP Any))
-> Ptr (SomeSEXP Any) -> IO (SomeSEXP Any)
forall a b. (a -> b) -> a -> b
$ Ptr () -> Ptr (SomeSEXP Any)
forall a b. Ptr a -> Ptr b
castPtr (Ptr () -> Ptr (SomeSEXP Any)) -> Ptr () -> Ptr (SomeSEXP Any)
forall a b. (a -> b) -> a -> b
$ SEXP Any 'Expr -> Ptr ()
forall s (a :: SEXPTYPE). SEXP s a -> Ptr ()
R.unsafeSEXPToVectorPtr SEXP Any 'Expr
exprs
        (forall s. R s (SomeSEXP V)) -> IO (SomeSEXP V)
forall a. NFData a => (forall s. R s a) -> IO a
runRegion ((forall s. R s (SomeSEXP V)) -> IO (SomeSEXP V))
-> (forall s. R s (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ do
          SomeSEXP val :: SEXP s a
val <- SEXP Any a -> R s (SomeSEXP (Region (R s)))
forall (m :: * -> *) s (a :: SEXPTYPE).
MonadR m =>
SEXP s a -> m (SomeSEXP (Region m))
eval SEXP Any a
expr
          SomeSEXP V -> R s (SomeSEXP V)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeSEXP V -> R s (SomeSEXP V)) -> SomeSEXP V -> R s (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ SEXP V a -> SomeSEXP V
forall s (a :: SEXPTYPE). SEXP s a -> SomeSEXP s
SomeSEXP (SEXP s a -> SEXP V a
forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s a
val)

-- | Parse file and perform some actions on parsed file.
--
-- This function uses continuation because this is an easy way to make
-- operations GC-safe.
parseFile :: FilePath -> (SEXP s 'R.Expr -> IO a) -> IO a
{-# DEPRECATED parseFile "Use [r| parse(file=\"path/to/file\") |] instead." #-}
parseFile :: String -> (SEXP s 'Expr -> IO a) -> IO a
parseFile fl :: String
fl f :: SEXP s 'Expr -> IO a
f = do
    String -> (CString -> IO a) -> IO a
forall a. String -> (CString -> IO a) -> IO a
withCString String
fl ((CString -> IO a) -> IO a) -> (CString -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \cfl :: CString
cfl ->
      IO (SEXP V 'String) -> (SEXP Any 'String -> IO a) -> IO a
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (CString -> IO (SEXP V 'String)
R.mkString CString
cfl) ((SEXP Any 'String -> IO a) -> IO a)
-> (SEXP Any 'String -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \rfl :: SEXP Any 'String
rfl ->
        ByteString -> SEXP Any 'String -> IO (SomeSEXP V)
forall s (a :: SEXPTYPE). ByteString -> SEXP s a -> IO (SomeSEXP V)
r1 (String -> ByteString
C8.pack "parse") SEXP Any 'String
rfl IO (SomeSEXP V) -> (SomeSEXP V -> IO a) -> IO a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(R.SomeSEXP s :: SEXP V a
s) ->
          SEXP V 'Expr -> IO (SEXP V 'Expr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SEXP V a -> SEXP V 'Expr
forall s (a :: SEXPTYPE) (b :: SEXPTYPE). SEXP s a -> SEXP s b
R.unsafeCoerce SEXP V a
s) IO (SEXP V 'Expr) -> (SEXP s 'Expr -> IO a) -> IO a
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
`R.withProtected` SEXP s 'Expr -> IO a
f

parseText
  :: String -- ^ Text to parse
  -> Bool   -- ^ Whether to annotate the AST with source locations.
  -> IO (R.SEXP V 'R.Expr)
{-# DEPRECATED parseText "Use [r| parse(text=...) |] instead." #-}
parseText :: String -> Bool -> IO (SEXP V 'Expr)
parseText txt :: String
txt b :: Bool
b = do
    SomeSEXP V
s <- ByteString -> IO (SomeSEXP V)
parseEval (ByteString -> IO (SomeSEXP V)) -> ByteString -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ String -> ByteString
C8.pack (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$
         "parse(text=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
txt String -> String -> String
forall a. [a] -> [a] -> [a]
++ ", keep.source=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
keep String -> String -> String
forall a. [a] -> [a] -> [a]
++ ")"
    SEXP V 'Expr -> IO (SEXP V 'Expr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SEXP V 'Expr -> IO (SEXP V 'Expr))
-> SEXP V 'Expr -> IO (SEXP V 'Expr)
forall a b. (a -> b) -> a -> b
$ (SSEXPTYPE 'Expr
forall k (a :: k). SingI a => Sing a
sing :: R.SSEXPTYPE 'R.Expr) SSEXPTYPE 'Expr -> SomeSEXP V -> SEXP V 'Expr
forall (a :: SEXPTYPE) s. SSEXPTYPE a -> SomeSEXP s -> SEXP s a
`R.cast` SomeSEXP V
s
  where
    keep :: String
keep | Bool
b         = "TRUE"
         | Bool
otherwise = "FALSE"

-- | Internalize a symbol name.
install :: MonadR m => String -> m (SEXP V 'R.Symbol)
install :: String -> m (SEXP V 'Symbol)
install = IO (SEXP V 'Symbol) -> m (SEXP V 'Symbol)
forall (m :: * -> *) a. MonadR m => IO a -> m a
io (IO (SEXP V 'Symbol) -> m (SEXP V 'Symbol))
-> (String -> IO (SEXP V 'Symbol)) -> String -> m (SEXP V 'Symbol)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO (SEXP V 'Symbol)
installIO

{-# DEPRECATED string, strings "Use mkSEXP instead" #-}

-- | Create an R character string from a Haskell string.
string :: String -> IO (SEXP V 'R.Char)
string :: String -> IO (SEXP V 'Char)
string str :: String
str = String -> (CString -> IO (SEXP V 'Char)) -> IO (SEXP V 'Char)
forall a. String -> (CString -> IO a) -> IO a
withCString String
str CString -> IO (SEXP V 'Char)
R.mkChar

-- | Create an R string vector from a Haskell string.
strings :: String -> IO (SEXP V 'R.String)
strings :: String -> IO (SEXP V 'String)
strings str :: String
str = String -> (CString -> IO (SEXP V 'String)) -> IO (SEXP V 'String)
forall a. String -> (CString -> IO a) -> IO a
withCString String
str CString -> IO (SEXP V 'String)
R.mkString

-- | Evaluate a (sequence of) expression(s) in the given environment, returning the
-- value of the last.
evalEnv :: MonadR m => SEXP s a -> SEXP s 'R.Env -> m (SomeSEXP (Region m))
evalEnv :: SEXP s a -> SEXP s 'Env -> m (SomeSEXP (Region m))
evalEnv (SEXP s a -> HExp s a
forall s (a :: SEXPTYPE). SEXP s a -> HExp s a
hexp -> Language.R.HExp.Expr _ v :: Vector 'Expr (SomeSEXP V)
v) rho :: SEXP s 'Env
rho = SomeSEXP V -> m (SomeSEXP (Region m))
forall (m :: * -> *).
MonadR m =>
SomeSEXP V -> m (SomeSEXP (Region m))
acquireSome (SomeSEXP V -> m (SomeSEXP (Region m)))
-> m (SomeSEXP V) -> m (SomeSEXP (Region m))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< do
    IO (SomeSEXP V) -> m (SomeSEXP V)
forall (m :: * -> *) a. MonadR m => IO a -> m a
io (IO (SomeSEXP V) -> m (SomeSEXP V))
-> IO (SomeSEXP V) -> m (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ (Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \p :: Ptr CInt
p -> do
      (SomeSEXP V -> IO ()) -> [SomeSEXP V] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(SomeSEXP s :: SEXP V a
s) -> IO (SEXP G a) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (SEXP G a) -> IO ()) -> IO (SEXP G a) -> IO ()
forall a b. (a -> b) -> a -> b
$ SEXP V a -> IO (SEXP G a)
forall s (a :: SEXPTYPE). SEXP s a -> IO (SEXP G a)
R.protect SEXP V a
s) (Vector 'Expr (SomeSEXP V) -> [SomeSEXP V]
forall (ty :: SEXPTYPE) a. SVECTOR ty a => Vector ty a -> [a]
Vector.toList Vector 'Expr (SomeSEXP V)
v)
      SomeSEXP V
x <- [SomeSEXP V] -> SomeSEXP V
forall a. [a] -> a
Prelude.last ([SomeSEXP V] -> SomeSEXP V) -> IO [SomeSEXP V] -> IO (SomeSEXP V)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SomeSEXP V] -> (SomeSEXP V -> IO (SomeSEXP V)) -> IO [SomeSEXP V]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (Vector 'Expr (SomeSEXP V) -> [SomeSEXP V]
forall (ty :: SEXPTYPE) a. SVECTOR ty a => Vector ty a -> [a]
Vector.toList Vector 'Expr (SomeSEXP V)
v) (\(SomeSEXP s :: SEXP V a
s) -> do
          SomeSEXP V
z <- SEXP V a -> SEXP V 'Env -> Ptr CInt -> IO (SomeSEXP V)
forall s (a :: SEXPTYPE).
SEXP s a -> SEXP s 'Env -> Ptr CInt -> IO (SomeSEXP V)
R.tryEvalSilent SEXP V a
s (SEXP s 'Env -> SEXP V 'Env
forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s 'Env
rho) Ptr CInt
p
          CInt
e <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
p
          Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CInt
e CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= 0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall s. R s ()) -> IO ()
forall a. NFData a => (forall s. R s a) -> IO a
runRegion ((forall s. R s ()) -> IO ()) -> (forall s. R s ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ SEXP s 'Env -> R s ()
forall (m :: * -> *) s a. MonadR m => SEXP s 'Env -> m a
throwR SEXP s 'Env
rho
          SomeSEXP V -> IO (SomeSEXP V)
forall (m :: * -> *) a. Monad m => a -> m a
return SomeSEXP V
z)
      Int -> IO ()
R.unprotect (Vector 'Expr (SomeSEXP V) -> Int
forall (ty :: SEXPTYPE) a. SVECTOR ty a => Vector ty a -> Int
Vector.length Vector 'Expr (SomeSEXP V)
v)
      SomeSEXP V -> IO (SomeSEXP V)
forall (m :: * -> *) a. Monad m => a -> m a
return SomeSEXP V
x
evalEnv x :: SEXP s a
x rho :: SEXP s 'Env
rho = SomeSEXP V -> m (SomeSEXP (Region m))
forall (m :: * -> *).
MonadR m =>
SomeSEXP V -> m (SomeSEXP (Region m))
acquireSome (SomeSEXP V -> m (SomeSEXP (Region m)))
-> m (SomeSEXP V) -> m (SomeSEXP (Region m))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< do
    IO (SomeSEXP V) -> m (SomeSEXP V)
forall (m :: * -> *) a. MonadR m => IO a -> m a
io (IO (SomeSEXP V) -> m (SomeSEXP V))
-> IO (SomeSEXP V) -> m (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ (Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (Ptr CInt -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \p :: Ptr CInt
p -> IO (SEXP V a) -> (SEXP Any a -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (SEXP V a -> IO (SEXP V a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SEXP s a -> SEXP V a
forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s a
x)) ((SEXP Any a -> IO (SomeSEXP V)) -> IO (SomeSEXP V))
-> (SEXP Any a -> IO (SomeSEXP V)) -> IO (SomeSEXP V)
forall a b. (a -> b) -> a -> b
$ \_ -> do
      SomeSEXP V
v <- SEXP s a -> SEXP s 'Env -> Ptr CInt -> IO (SomeSEXP V)
forall s (a :: SEXPTYPE).
SEXP s a -> SEXP s 'Env -> Ptr CInt -> IO (SomeSEXP V)
R.tryEvalSilent SEXP s a
x SEXP s 'Env
rho Ptr CInt
p
      CInt
e <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
p
      Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CInt
e CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= 0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall s. R s ()) -> IO ()
forall a. NFData a => (forall s. R s a) -> IO a
runRegion ((forall s. R s ()) -> IO ()) -> (forall s. R s ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ SEXP s 'Env -> R s ()
forall (m :: * -> *) s a. MonadR m => SEXP s 'Env -> m a
throwR SEXP s 'Env
rho
      SomeSEXP V -> IO (SomeSEXP V)
forall (m :: * -> *) a. Monad m => a -> m a
return SomeSEXP V
v

-- | Evaluate a (sequence of) expression(s) in the global environment.
eval :: MonadR m => SEXP s a -> m (SomeSEXP (Region m))
eval :: SEXP s a -> m (SomeSEXP (Region m))
eval x :: SEXP s a
x = SEXP s a -> SEXP s 'Env -> m (SomeSEXP (Region m))
forall (m :: * -> *) s (a :: SEXPTYPE).
MonadR m =>
SEXP s a -> SEXP s 'Env -> m (SomeSEXP (Region m))
evalEnv SEXP s a
x (SEXP G 'Env -> SEXP s 'Env
forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP G 'Env
globalEnv)

-- | Silent version of 'eval' function that discards it's result.
eval_ :: MonadR m => SEXP s a -> m ()
eval_ :: SEXP s a -> m ()
eval_ = m (SomeSEXP (PrimState m)) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (SomeSEXP (PrimState m)) -> m ())
-> (SEXP s a -> m (SomeSEXP (PrimState m))) -> SEXP s a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SEXP s a -> m (SomeSEXP (PrimState m))
forall (m :: * -> *) s (a :: SEXPTYPE).
MonadR m =>
SEXP s a -> m (SomeSEXP (Region m))
eval

-- | Throw an R error as an exception.
throwR :: MonadR m => R.SEXP s 'R.Env   -- ^ Environment in which to find error.
       -> m a
throwR :: SEXP s 'Env -> m a
throwR env :: SEXP s 'Env
env = SEXP s 'Env -> m String
forall (m :: * -> *) s. MonadR m => SEXP s 'Env -> m String
getErrorMessage SEXP s 'Env
env m String -> (String -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO a -> m a
forall (m :: * -> *) a. MonadR m => IO a -> m a
io (IO a -> m a) -> (String -> IO a) -> String -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RError -> IO a
forall e a. Exception e => e -> IO a
throwIO (RError -> IO a) -> (String -> RError) -> String -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> RError
R.RError

-- | Cancel any ongoing R computation in the current process. After interruption
-- an 'RError' exception will be raised.
--
-- This call is safe to run in any thread. If there is no R computation running,
-- the next computaion will be immediately cancelled. Note that R will only
-- interrupt computations at so-called "safe points" (in particular, not in the
-- middle of a C call).
cancel :: IO ()
cancel :: IO ()
cancel = Ptr CInt -> CInt -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CInt
R.interruptsPending 1

-- | Throw an R exception with specified message.
throwRMessage :: MonadR m => String -> m a
throwRMessage :: String -> m a
throwRMessage = IO a -> m a
forall (m :: * -> *) a. MonadR m => IO a -> m a
io (IO a -> m a) -> (String -> IO a) -> String -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RError -> IO a
forall e a. Exception e => e -> IO a
throwIO (RError -> IO a) -> (String -> RError) -> String -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> RError
R.RError

-- | Read last error message.
getErrorMessage :: MonadR m => R.SEXP s 'R.Env -> m String
getErrorMessage :: SEXP s 'Env -> m String
getErrorMessage e :: SEXP s 'Env
e = IO String -> m String
forall (m :: * -> *) a. MonadR m => IO a -> m a
io (IO String -> m String) -> IO String -> m String
forall a b. (a -> b) -> a -> b
$ do
  IO (SEXP V 'Lang) -> (SEXP Any 'Lang -> IO String) -> IO String
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (String -> (CString -> IO (SEXP V 'Lang)) -> IO (SEXP V 'Lang)
forall a. String -> (CString -> IO a) -> IO a
withCString "geterrmessage" ((CString -> IO (SEXP V 'Symbol)
R.install (CString -> IO (SEXP V 'Symbol))
-> (SEXP V 'Symbol -> IO (SEXP V 'Lang))
-> CString
-> IO (SEXP V 'Lang)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> SEXP V 'Symbol -> IO (SEXP V 'Lang)
forall s (a :: SEXPTYPE). SEXP s a -> IO (SEXP V 'Lang)
R.lang1))) ((SEXP Any 'Lang -> IO String) -> IO String)
-> (SEXP Any 'Lang -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \f :: SEXP Any 'Lang
f -> do
    IO (SEXP V 'Env) -> (SEXP Any 'Env -> IO String) -> IO String
forall (a :: SEXPTYPE) s b.
IO (SEXP V a) -> (SEXP s a -> IO b) -> IO b
R.withProtected (SEXP V 'Env -> IO (SEXP V 'Env)
forall (m :: * -> *) a. Monad m => a -> m a
return (SEXP s 'Env -> SEXP V 'Env
forall t s (a :: SEXPTYPE). (t <= s) => SEXP s a -> SEXP t a
R.release SEXP s 'Env
e)) ((SEXP Any 'Env -> IO String) -> IO String)
-> (SEXP Any 'Env -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \env :: SEXP Any 'Env
env -> do
      CString -> IO String
peekCString
        (CString -> IO String) -> IO CString -> IO String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SEXP V 'Char -> IO CString
forall s. SEXP s 'Char -> IO CString
R.char
        (SEXP V 'Char -> IO CString) -> IO (SEXP V 'Char) -> IO CString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (SEXP V 'Char) -> IO (SEXP V 'Char)
forall a. Storable a => Ptr a -> IO a
peek
        (Ptr (SEXP V 'Char) -> IO (SEXP V 'Char))
-> IO (Ptr (SEXP V 'Char)) -> IO (SEXP V 'Char)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SEXP V 'String -> IO (Ptr (SEXP V 'Char))
forall s. SEXP s 'String -> IO (Ptr (SEXP s 'Char))
R.string (SEXP V 'String -> IO (Ptr (SEXP V 'Char)))
-> (SomeSEXP V -> SEXP V 'String)
-> SomeSEXP V
-> IO (Ptr (SEXP V 'Char))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SSEXPTYPE 'String -> SomeSEXP V -> SEXP V 'String
forall (a :: SEXPTYPE) s. SSEXPTYPE a -> SomeSEXP s -> SEXP s a
R.cast (SSEXPTYPE 'String
forall k (a :: k). SingI a => Sing a
sing :: R.SSEXPTYPE 'R.String)
        (SomeSEXP V -> IO (Ptr (SEXP V 'Char)))
-> IO (SomeSEXP V) -> IO (Ptr (SEXP V 'Char))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SEXP Any 'Lang -> SEXP Any 'Env -> IO (SomeSEXP V)
forall s (a :: SEXPTYPE).
SEXP s a -> SEXP s 'Env -> IO (SomeSEXP V)
R.eval SEXP Any 'Lang
f SEXP Any 'Env
env