{-# LANGUAGE TypeApplications #-}
module HsLua.Core.Trace
( pcallTrace
, callTrace
, dofileTrace
, dostringTrace
) where
import Data.ByteString (ByteString)
import Foreign.C.Types
import HsLua.Core.Auxiliary (loadfile, loadstring, tostring', traceback)
import HsLua.Core.Error (Exception, LuaError, throwErrorAsException)
import HsLua.Core.Primary (gettop, insert, pcall, pushcfunction, remove)
import HsLua.Core.Run (runWith)
import HsLua.Core.Types
( CFunction, LuaE, NumArgs (..), NumResults (..), PreCFunction
, Status (OK), State (..), multret )
pcallTrace :: NumArgs -> NumResults -> LuaE e Status
pcallTrace :: NumArgs -> NumResults -> LuaE e Status
pcallTrace nargs :: NumArgs
nargs@(NumArgs CInt
nargsint) NumResults
nres = do
StackIndex
curtop <- LuaE e StackIndex
forall e. LuaE e StackIndex
gettop
let base :: StackIndex
base = StackIndex
curtop StackIndex -> StackIndex -> StackIndex
forall a. Num a => a -> a -> a
- CInt -> StackIndex
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
nargsint
CFunction -> LuaE e ()
forall e. CFunction -> LuaE e ()
pushcfunction CFunction
hsluaL_msghandler_ptr
StackIndex -> LuaE e ()
forall e. StackIndex -> LuaE e ()
insert StackIndex
base
Status
status' <- NumArgs -> NumResults -> Maybe StackIndex -> LuaE e Status
forall e.
NumArgs -> NumResults -> Maybe StackIndex -> LuaE e Status
pcall NumArgs
nargs NumResults
nres (StackIndex -> Maybe StackIndex
forall a. a -> Maybe a
Just StackIndex
base)
StackIndex -> LuaE e ()
forall e. StackIndex -> LuaE e ()
remove StackIndex
base
Status -> LuaE e Status
forall (m :: * -> *) a. Monad m => a -> m a
return Status
status'
callTrace :: LuaError e => NumArgs -> NumResults -> LuaE e ()
callTrace :: NumArgs -> NumResults -> LuaE e ()
callTrace NumArgs
nargs NumResults
nres = NumArgs -> NumResults -> LuaE e Status
forall e. NumArgs -> NumResults -> LuaE e Status
pcallTrace NumArgs
nargs NumResults
nres LuaE e Status -> (Status -> LuaE e ()) -> LuaE e ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Status
OK -> () -> LuaE e ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Status
_ -> LuaE e ()
forall e a. LuaError e => LuaE e a
throwErrorAsException
dofileTrace :: FilePath -> LuaE e Status
dofileTrace :: FilePath -> LuaE e Status
dofileTrace FilePath
fp = FilePath -> LuaE e Status
forall e. FilePath -> LuaE e Status
loadfile FilePath
fp LuaE e Status -> (Status -> LuaE e Status) -> LuaE e Status
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Status
OK -> NumArgs -> NumResults -> LuaE e Status
forall e. NumArgs -> NumResults -> LuaE e Status
pcallTrace NumArgs
0 NumResults
multret
Status
s -> Status -> LuaE e Status
forall (f :: * -> *) a. Applicative f => a -> f a
pure Status
s
dostringTrace :: ByteString -> LuaE e Status
dostringTrace :: ByteString -> LuaE e Status
dostringTrace ByteString
s = ByteString -> LuaE e Status
forall e. ByteString -> LuaE e Status
loadstring ByteString
s LuaE e Status -> (Status -> LuaE e Status) -> LuaE e Status
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Status
OK -> NumArgs -> NumResults -> LuaE e Status
forall e. NumArgs -> NumResults -> LuaE e Status
pcallTrace NumArgs
0 NumResults
multret
Status
err -> Status -> LuaE e Status
forall (f :: * -> *) a. Applicative f => a -> f a
pure Status
err
hsluaL_msghandler :: State -> IO NumResults
hsluaL_msghandler :: State -> IO NumResults
hsluaL_msghandler State
l = State -> LuaE Exception NumResults -> IO NumResults
forall e a. State -> LuaE e a -> IO a
runWith State
l (LuaE Exception NumResults -> IO NumResults)
-> LuaE Exception NumResults -> IO NumResults
forall a b. (a -> b) -> a -> b
$ do
ByteString
msg <- StackIndex -> LuaE Exception ByteString
forall e. LuaError e => StackIndex -> LuaE e ByteString
tostring' @Exception StackIndex
1
State -> Maybe ByteString -> Int -> LuaE Exception ()
forall e. State -> Maybe ByteString -> Int -> LuaE e ()
traceback State
l (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
msg) Int
2
NumResults -> LuaE Exception NumResults
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CInt -> NumResults
NumResults CInt
1)
foreign export ccall hsluaL_msghandler :: PreCFunction
foreign import ccall "&hsluaL_msghandler"
hsluaL_msghandler_ptr:: CFunction