    {-# LANGUAGE OverloadedStrings #-}
    {-|
    Module      : HsLua.Core.Primary
    Copyright   : © 2007–2012 Gracjan Polak;
                  © 2012–2016 Ömer Sinan Ağacan;
                  © 2017-2024 Albert Krewinkel
    License     : MIT
    Maintainer  : Albert Krewinkel <tarleb@hslua.org>
    Stability   : beta
    Portability : non-portable (depends on GHC)

    Monadic functions which operate within the Lua type.

    The functions in this module are mostly thin wrappers around the
    respective C functions. However, C function which can throw an error are
    wrapped such that the error is converted into an exception.
    -}
    module HsLua.Core.Primary where

    import Prelude hiding (EQ, LT, compare, concat, error)

    import Control.Monad
    import Data.ByteString (ByteString)
    import Data.Maybe (fromMaybe)
    import HsLua.Core.Error
    import HsLua.Core.Types as Lua
    import Lua
    import Foreign.Marshal.Alloc (alloca)
    import Foreign.Ptr

    import qualified Data.ByteString as B
    import qualified Data.ByteString.Unsafe as B
    import qualified Foreign.Storable as F

    --
    -- Helper functions
    --

    -- | Execute an action only if the given index is a table. Throw an
    -- error otherwise.
    ensureTable :: LuaError e => StackIndex -> (Lua.State -> IO a) -> LuaE e a
    ensureTable :: forall e a. LuaError e => StackIndex -> (State -> IO a) -> LuaE e a
    ensureTable StackIndex
    idx State -> IO a
    ioOp = do
      isTbl <- StackIndex -> LuaE e Bool
    forall e. StackIndex -> LuaE e Bool
    istable StackIndex
    idx
      if isTbl
        then liftLua ioOp
        else throwTypeMismatchError "table" idx
    {-# INLINE ensureTable #-}

    --
    -- API functions
    --

    -- | Converts the acceptable index @idx@ into an equivalent absolute
    -- index (that is, one that does not depend on the stack top).
    --
    -- Wraps 'lua_absindex'.
    absindex :: StackIndex -> LuaE e StackIndex
    absindex :: forall e. StackIndex -> LuaE e StackIndex
    absindex = (State -> StackIndex -> IO StackIndex)
    -> StackIndex -> LuaE e StackIndex
    forall a b e. (State -> a -> IO b) -> a -> LuaE e b
    liftLua1 State -> StackIndex -> IO StackIndex
    lua_absindex
    {-# INLINABLE absindex #-}

    -- |  Calls a function.
    --
    -- To call a function you must use the following protocol: first, the
    -- function to be called is pushed onto the stack; then, the arguments
    -- to the function are pushed in direct order; that is, the first
    -- argument is pushed first. Finally you call @call@; @nargs@ is the
    -- number of arguments that you pushed onto the stack. All arguments and
    -- the function value are popped from the stack when the function is
    -- called. The function results are pushed onto the stack when the
    -- function returns. The number of results is adjusted to @nresults@,
    -- unless @nresults@ is @multret@. In this case, all results from the
    -- function are pushed. Lua takes care that the returned values fit into
    -- the stack space. The function results are pushed onto the stack in
    -- direct order (the first result is pushed first), so that after the
    -- call the last result is on the top of the stack.
    --
    -- Any error inside the called function is propagated as exception of
    -- type @e@.
    --
    -- The following example shows how the host program can do the
    -- equivalent to this Lua code:
    --
    -- > a = f("how", t.x, 14)
    --
    -- Here it is in Haskell (assuming the OverloadedStrings language
    -- extension):
    --
    -- > getglobal "f"         -- function to be called
    -- > pushstring  "how"     -- 1st argument
    -- > getglobal "t"         -- table to be indexed
    -- > getfield (-1) "x"     -- push result of t.x (2nd arg)
    -- > remove (-2)           -- remove 't' from the stack
    -- > pushinteger 14        -- 3rd argument
    -- > call 3 1              -- call 'f' with 3 arguments and 1 result
    -- > setglobal "a"         -- set global 'a'
    --
    -- Note that the code above is "balanced": at its end, the stack is back
    -- to its original configuration. This is considered good programming
    -- practice.
    --
    -- See <https://www.lua.org/manual/5.4/manual.html#lua_call lua_call>.
    call :: LuaError e => NumArgs -> NumResults -> LuaE e ()
    call :: forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    nargs NumResults
    nresults = do
      res <- NumArgs -> NumResults -> Maybe StackIndex -> LuaE e Status
    forall e.
    NumArgs -> NumResults -> Maybe StackIndex -> LuaE e Status
    pcall NumArgs
    nargs NumResults
    nresults Maybe StackIndex
    forall a. Maybe a
    Nothing
      when (res /= OK) throwErrorAsException
    {-# INLINABLE call #-}

    -- | Ensures that the stack has space for at least @n@ extra slots (that
    -- is, that you can safely push up to @n@ values into it). It returns
    -- false if it cannot fulfill the request, either because it would cause
    -- the stack to be larger than a fixed maximum size (typically at least
    -- several thousand elements) or because it cannot allocate memory for
    -- the extra space. This function never shrinks the stack; if the stack
    -- already has space for the extra slots, it is left unchanged.
    --
    -- Wraps 'lua_checkstack'.
    checkstack :: Int -> LuaE e Bool
    checkstack :: forall e. Int -> LuaE e Bool
    checkstack Int
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> CInt -> IO LuaBool
    lua_checkstack State
    l (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)
    {-# INLINABLE checkstack #-}

    -- | Destroys all objects in the given Lua state (calling the
    -- corresponding garbage-collection metamethods, if any) and frees all
    -- dynamic memory used by this state. On several platforms, you may not
    -- need to call this function, because all resources are naturally
    -- released when the host program ends. On the other hand, long-running
    -- programs that create multiple states, such as daemons or web servers,
    -- will probably need to close states as soon as they are not needed.
    --
    -- Same as 'lua_close'.
    close :: Lua.State -> IO ()
    close :: State -> IO ()
    close = State -> IO ()
    lua_close
    {-# INLINABLE close #-}

    -- | Compares two Lua values. Returns 'True' if the value at index
    -- @idx1@ satisfies @op@ when compared with the value at index @idx2@,
    -- following the semantics of the corresponding Lua operator (that is,
    -- it may call metamethods). Otherwise returns @False@. Also returns
    -- @False@ if any of the indices is not valid.
    --
    -- The value of op must be of type 'RelationalOperator':
    --
    --    EQ: compares for equality (==)
    --    LT: compares for less than (<)
    --    LE: compares for less or equal (<=)
    --
    -- Wraps 'hslua_compare'. See also
    -- <https://www.lua.org/manual/5.4/manual.html#lua_compare lua_compare>.
    compare :: LuaError e
            => StackIndex         -- ^ idx1
            -> StackIndex         -- ^ idx2
            -> RelationalOperator
            -> LuaE e Bool
    compare :: forall e.
    LuaError e =>
    StackIndex -> StackIndex -> RelationalOperator -> LuaE e Bool
    compare StackIndex
    idx1 StackIndex
    idx2 RelationalOperator
    relOp = LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> LuaE e LuaBool -> LuaE e Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> (State -> Ptr StatusCode -> IO LuaBool) -> LuaE e LuaBool
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow
      (\State
    l -> State
    -> StackIndex
    -> StackIndex
    -> OPCode
    -> Ptr StatusCode
    -> IO LuaBool
    hslua_compare State
    l StackIndex
    idx1 StackIndex
    idx2 (RelationalOperator -> OPCode
    fromRelationalOperator RelationalOperator
    relOp))
    {-# INLINABLE compare #-}

    -- | Concatenates the @n@ values at the top of the stack, pops them, and
    -- leaves the result at the top. If @n@ is 1, the result is the single
    -- value on the stack (that is, the function does nothing); if @n@ is 0,
    -- the result is the empty string. Concatenation is performed following
    -- the usual semantics of Lua (see
    -- <https://www.lua.org/manual/5.4/manual.html#3.4.6 §3.4.6> of the Lua
    -- manual).
    --
    -- Wraps 'hslua_concat'. See also
    -- <https://www.lua.org/manual/5.4/manual.html#lua_concat lua_concat>.
    concat :: LuaError e => NumArgs -> LuaE e ()
    concat :: forall e. LuaError e => NumArgs -> LuaE e ()
    concat NumArgs
    n = (State -> Ptr StatusCode -> IO ()) -> LuaE e ()
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow (State -> NumArgs -> Ptr StatusCode -> IO ()
    `hslua_concat` NumArgs
    n)
    {-# INLINABLE concat #-}

    -- | Copies the element at index @fromidx@ into the valid index @toidx@,
    -- replacing the value at that position. Values at other positions are
    -- not affected.
    --
    -- Wraps 'lua_copy'.
    copy :: StackIndex -> StackIndex -> LuaE e ()
    copy :: forall e. StackIndex -> StackIndex -> LuaE e ()
    copy StackIndex
    fromidx StackIndex
    toidx = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> StackIndex -> IO ()
    lua_copy State
    l StackIndex
    fromidx StackIndex
    toidx
    {-# INLINABLE copy #-}

    -- | Creates a new empty table and pushes it onto the stack. Parameter
    -- narr is a hint for how many elements the table will have as a
    -- sequence; parameter nrec is a hint for how many other elements the
    -- table will have. Lua may use these hints to preallocate memory for
    -- the new table. This preallocation is useful for performance when you
    -- know in advance how many elements the table will have. Otherwise you
    -- can use the function lua_newtable.
    --
    -- Wraps 'lua_createtable'.
    createtable :: Int -> Int -> LuaE e ()
    createtable :: forall e. Int -> Int -> LuaE e ()
    createtable Int
    narr Int
    nrec = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      State -> CInt -> CInt -> IO ()
    lua_createtable State
    l (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    narr) (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nrec)
    {-# INLINABLE createtable #-}

    -- TODO: implement dump

    -- | Returns @True@ if the two values in acceptable indices @index1@ and
    -- @index2@ are equal, following the semantics of the Lua @==@ operator
    -- (that is, may call metamethods). Otherwise returns @False@. Also
    -- returns @False@ if any of the indices is non valid. Uses @'compare'@
    -- internally.
    equal :: LuaError e
          => StackIndex  -- ^ index1
          -> StackIndex  -- ^ index2
          -> LuaE e Bool
    equal :: forall e. LuaError e => StackIndex -> StackIndex -> LuaE e Bool
    equal StackIndex
    index1 StackIndex
    index2 = StackIndex -> StackIndex -> RelationalOperator -> LuaE e Bool
    forall e.
    LuaError e =>
    StackIndex -> StackIndex -> RelationalOperator -> LuaE e Bool
    compare StackIndex
    index1 StackIndex
    index2 RelationalOperator
    EQ
    {-# INLINABLE equal #-}

    -- | Signals to Lua that an error has occurred and that the error object
    -- is at the top of the stack.
    error :: LuaE e NumResults
    error :: forall e. LuaE e NumResults
    error = (State -> IO NumResults) -> LuaE e NumResults
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO NumResults
    hslua_error
    {-# INLINABLE error #-}

    -- |  Controls the garbage collector.
    --
    -- This function performs several tasks, according to the given control
    -- command. See the documentation for 'GCControl'.
    --
    -- Wraps 'lua_gc'.
    gc :: GCControl -> LuaE e Int
    gc :: forall e. GCControl -> LuaE e Int
    gc GCControl
    what = (State -> IO Int) -> LuaE e Int
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Int) -> LuaE e Int)
    -> (State -> IO Int) -> LuaE e Int
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> do
      let (CInt
    data1, CInt
    data2, CInt
    data3) = GCControl -> (CInt, CInt, CInt)
    toGCdata GCControl
    what
      CInt -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (CInt -> Int) -> IO CInt -> IO Int
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> GCCode -> CInt -> CInt -> CInt -> IO CInt
    lua_gc State
    l (GCControl -> GCCode
    toGCcode GCControl
    what) CInt
    data1 CInt
    data2 CInt
    data3
    {-# INLINABLE gc #-}

    -- | Pushes onto the stack the value @t[k]@, where @t@ is the value at
    -- the given stack index. As in Lua, this function may trigger a
    -- metamethod for the "index" event (see
    -- <https://www.lua.org/manual/5.4/manual.html#2.4 §2.4> of Lua's
    -- manual).
    --
    -- Errors on the Lua side are propagated.
    --
    -- See also
    -- <https://www.lua.org/manual/5.4/manual.html#lua_getfield lua_getfield>.
    getfield :: LuaError e => StackIndex -> Name -> LuaE e Type
    getfield :: forall e. LuaError e => StackIndex -> Name -> LuaE e Type
    getfield StackIndex
    i (Name ByteString
    s) = do
      absidx <- StackIndex -> LuaE e StackIndex
    forall e. StackIndex -> LuaE e StackIndex
    absindex StackIndex
    i
      pushstring s
      gettable absidx
    {-# INLINABLE getfield #-}

    -- | Pushes onto the stack the value of the global @name@.
    --
    -- Errors on the Lua side are propagated.
    --
    -- Wraps 'hslua_getglobal'.
    getglobal :: LuaError e => Name -> LuaE e Type
    getglobal :: forall e. LuaError e => Name -> LuaE e Type
    getglobal (Name ByteString
    name) = (State -> Ptr StatusCode -> IO Type) -> LuaE e Type
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow ((State -> Ptr StatusCode -> IO Type) -> LuaE e Type)
    -> (State -> Ptr StatusCode -> IO Type) -> LuaE e Type
    forall a b. (a -> b) -> a -> b
    $ \State
    l Ptr StatusCode
    status' ->
      ByteString -> (CStringLen -> IO Type) -> IO Type
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    B.unsafeUseAsCStringLen ByteString
    name ((CStringLen -> IO Type) -> IO Type)
    -> (CStringLen -> IO Type) -> IO Type
    forall a b. (a -> b) -> a -> b
    $ \(Ptr CChar
    namePtr, Int
    len) ->
      TypeCode -> Type
    toType (TypeCode -> Type) -> IO TypeCode -> IO Type
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> Ptr CChar -> CSize -> Ptr StatusCode -> IO TypeCode
    hslua_getglobal State
    l Ptr CChar
    namePtr (Int -> CSize
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    len) Ptr StatusCode
    status'
    {-# INLINABLE getglobal #-}

    -- | If the value at the given index has a metatable, the function
    -- pushes that metatable onto the stack and returns @True@. Otherwise,
    -- the function returns @False@ and pushes nothing on the stack.
    --
    -- Wraps 'lua_getmetatable'.
    getmetatable :: StackIndex -> LuaE e Bool
    getmetatable :: forall e. StackIndex -> LuaE e Bool
    getmetatable StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_getmetatable State
    l StackIndex
    n
    {-# INLINABLE getmetatable #-}

    -- | Pushes onto the stack the value @t[k]@, where @t@ is the value at
    -- the given index and @k@ is the value at the top of the stack.
    --
    -- This function pops the key from the stack, pushing the resulting
    -- value in its place. As in Lua, this function may trigger a metamethod
    -- for the "index" event (see
    -- <https://www.lua.org/manual/5.4/manual.html#2.4 §2.4> of Lua's
    -- manual).
    --
    -- Errors on the Lua side are caught and rethrown.
    --
    -- Wraps 'hslua_gettable'. See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_gettable lua_gettable>.
    gettable :: LuaError e => StackIndex -> LuaE e Type
    gettable :: forall e. LuaError e => StackIndex -> LuaE e Type
    gettable StackIndex
    n = (State -> Ptr StatusCode -> IO Type) -> LuaE e Type
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow (\State
    l -> (TypeCode -> Type) -> IO TypeCode -> IO Type
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap TypeCode -> Type
    toType (IO TypeCode -> IO Type)
    -> (Ptr StatusCode -> IO TypeCode) -> Ptr StatusCode -> IO Type
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . State -> StackIndex -> Ptr StatusCode -> IO TypeCode
    hslua_gettable State
    l StackIndex
    n)
    {-# INLINABLE gettable #-}

    -- | Returns the index of the top element in the stack. Because indices
    -- start at 1, this result is equal to the number of elements in the
    -- stack (and so 0 means an empty stack).
    --
    -- Wraps 'lua_gettop'.
    gettop :: LuaE e StackIndex
    gettop :: forall e. LuaE e StackIndex
    gettop = (State -> IO StackIndex) -> LuaE e StackIndex
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO StackIndex
    lua_gettop
    {-# INLINABLE gettop #-}

    -- | Pushes onto the stack the @n@-th user value associated with the
    -- full userdata at the given index and returns the type of the pushed
    -- value.
    --
    -- If the userdata does not have that value, pushes __nil__ and returns
    -- 'LUA_TNONE'.
    --
    -- Wraps 'lua_getiuservalue'.
    getiuservalue :: StackIndex  -- ^ index
                 -> Int         -- ^ n
                 -> LuaE e Type
    getiuservalue :: forall e. StackIndex -> Int -> LuaE e Type
    getiuservalue StackIndex
    idx Int
    n = (State -> IO Type) -> LuaE e Type
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Type) -> LuaE e Type)
    -> (State -> IO Type) -> LuaE e Type
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      TypeCode -> Type
    toType (TypeCode -> Type) -> IO TypeCode -> IO Type
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> CInt -> IO TypeCode
    lua_getiuservalue State
    l StackIndex
    idx (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)

    -- | Moves the top element into the given valid index, shifting up the
    -- elements above this index to open space. This function cannot be
    -- called with a pseudo-index, because a pseudo-index is not an actual
    -- stack position.
    --
    -- Wraps 'lua_insert'.
    insert :: StackIndex -> LuaE e ()
    insert :: forall e. StackIndex -> LuaE e ()
    insert StackIndex
    index = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> IO ()
    lua_insert State
    l StackIndex
    index
    {-# INLINABLE insert #-}

    -- | Returns 'True' if the value at the given index is a boolean, and
    -- 'False' otherwise.
    --
    -- Wraps 'lua_isboolean'.
    isboolean :: StackIndex -> LuaE e Bool
    isboolean :: forall e. StackIndex -> LuaE e Bool
    isboolean StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isboolean State
    l StackIndex
    n
    {-# INLINABLE isboolean #-}

    -- | Returns 'True' if the value at the given index is a C function, and
    -- 'False' otherwise.
    --
    -- Wraps 'lua_iscfunction'.
    iscfunction :: StackIndex -> LuaE e Bool
    iscfunction :: forall e. StackIndex -> LuaE e Bool
    iscfunction StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_iscfunction State
    l StackIndex
    n
    {-# INLINABLE iscfunction #-}

    -- | Returns 'True' if the value at the given index is a function
    -- (either C or Lua), and 'False' otherwise.
    --
    -- Wraps 'lua_isfunction'.
    isfunction :: StackIndex -> LuaE e Bool
    isfunction :: forall e. StackIndex -> LuaE e Bool
    isfunction StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isfunction State
    l StackIndex
    n
    {-# INLINABLE isfunction #-}

    -- | Returns @True@ if the value at the given index is an integer (that
    -- is, the value is a number and is represented as an integer), and
    -- 'False' otherwise.
    --
    -- Wraps 'lua_isinteger'.
    isinteger :: StackIndex -> LuaE e Bool
    isinteger :: forall e. StackIndex -> LuaE e Bool
    isinteger StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isinteger State
    l StackIndex
    n
    {-# INLINABLE isinteger #-}

    -- | Returns @True@ if the value at the given index is a light userdata,
    -- and @False@ otherwise.
    --
    -- Wraps 'lua_islightuserdata'.
    islightuserdata :: StackIndex -> LuaE e Bool
    islightuserdata :: forall e. StackIndex -> LuaE e Bool
    islightuserdata StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_islightuserdata State
    l StackIndex
    n
    {-# INLINABLE islightuserdata #-}

    -- | Returns 'True' if the value at the given index is *nil*, and
    -- 'False' otherwise.
    --
    -- Wraps 'lua_isnil'.
    isnil :: StackIndex -> LuaE e Bool
    isnil :: forall e. StackIndex -> LuaE e Bool
    isnil StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isnil State
    l StackIndex
    n
    {-# INLINABLE isnil #-}

    -- | Returns 'True' if the given index is not valid, and 'False'
    -- otherwise.
    --
    -- Wraps 'lua_isnone'.
    isnone :: StackIndex -> LuaE e Bool
    isnone :: forall e. StackIndex -> LuaE e Bool
    isnone StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isnone State
    l StackIndex
    n
    {-# INLINABLE isnone #-}

    -- | Returns 'True' if the given index is not valid or if the value at
    -- the given index is *nil*, and 'False' otherwise.
    --
    -- Wraps 'lua_isnoneornil'.
    isnoneornil :: StackIndex -> LuaE e Bool
    isnoneornil :: forall e. StackIndex -> LuaE e Bool
    isnoneornil StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isnoneornil State
    l StackIndex
    n
    {-# INLINABLE isnoneornil #-}

    -- | Returns 'True' if the value at the given index is a number or a
    -- string convertible to a number, and 'False' otherwise.
    --
    -- Wraps 'lua_isnumber'.
    isnumber :: StackIndex -> LuaE e Bool
    isnumber :: forall e. StackIndex -> LuaE e Bool
    isnumber StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isnumber State
    l StackIndex
    n
    {-# INLINABLE isnumber #-}

    -- | Returns 'True' if the value at the given index is a string or a
    -- number (which is always convertible to a string), and 'False'
    -- otherwise.
    --
    -- Wraps 'lua_isstring'.
    isstring :: StackIndex -> LuaE e Bool
    isstring :: forall e. StackIndex -> LuaE e Bool
    isstring StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isstring State
    l StackIndex
    n
    {-# INLINABLE isstring #-}

    -- | Returns 'True' if the value at the given index is a table, and
    -- 'False' otherwise.
    --
    -- Wraps 'lua_istable'.
    istable :: StackIndex -> LuaE e Bool
    istable :: forall e. StackIndex -> LuaE e Bool
    istable StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_istable State
    l StackIndex
    n
    {-# INLINABLE istable #-}

    -- | Returns 'True' if the value at the given index is a thread, and
    -- 'False' otherwise.
    --
    -- Wraps 'lua_isthread'.
    isthread :: StackIndex -> LuaE e Bool
    isthread :: forall e. StackIndex -> LuaE e Bool
    isthread StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isthread State
    l StackIndex
    n
    {-# INLINABLE isthread #-}

    -- | Returns 'True' if the value at the given index is a userdata
    -- (either full or light), and 'False' otherwise.
    --
    -- Wraps 'lua_isuserdata'.
    isuserdata :: StackIndex -> LuaE e Bool
    isuserdata :: forall e. StackIndex -> LuaE e Bool
    isuserdata StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_isuserdata State
    l StackIndex
    n
    {-# INLINABLE isuserdata #-}

    -- | Tests whether the object under the first index is smaller than that
    -- under the second. Uses @'compare'@ internally.
    lessthan :: LuaError e =>  StackIndex -> StackIndex -> LuaE e Bool
    lessthan :: forall e. LuaError e => StackIndex -> StackIndex -> LuaE e Bool
    lessthan StackIndex
    index1 StackIndex
    index2 = StackIndex -> StackIndex -> RelationalOperator -> LuaE e Bool
    forall e.
    LuaError e =>
    StackIndex -> StackIndex -> RelationalOperator -> LuaE e Bool
    compare StackIndex
    index1 StackIndex
    index2 RelationalOperator
    LT
    {-# INLINABLE lessthan #-}

    -- | Loads a Lua chunk (without running it). If there are no errors,
    -- @'load'@ pushes the compiled chunk as a Lua function on top of the
    -- stack. Otherwise, it pushes an error message.
    --
    -- The return values of @'load'@ are:
    --
    -- - @'OK'@: no errors;
    -- - @'ErrSyntax'@: syntax error during pre-compilation;
    -- - @'ErrMem'@: memory allocation error;
    -- - @'ErrGcmm'@: error while running a @__gc@ metamethod. (This error
    --   has no relation with the chunk being loaded. It is generated by the
    --   garbage collector.)
    --
    -- This function only loads a chunk; it does not run it.
    --
    -- @load@ automatically detects whether the chunk is text or binary, and
    -- loads it accordingly (see program luac).
    --
    -- The @'load'@ function uses a user-supplied reader function to read
    -- the chunk (see @'Lua.Reader'@). The data argument is an opaque value
    -- passed to the reader function.
    --
    -- The @chunkname@ argument gives a name to the chunk, which is used for
    -- error messages and in debug information (see
    -- <https://www.lua.org/manual/5.4/manual.html#4.7 §4.7>). Note that the
    -- @chunkname@ is used as a C string, so it may not contain null-bytes.
    --
    -- This is a wrapper of 'lua_load'.
    load :: Lua.Reader -> Ptr () -> Name -> LuaE e Status
    load :: forall e. Reader -> Ptr () -> Name -> LuaE e Status
    load Reader
    reader Ptr ()
    data' (Name ByteString
    chunkname) = (State -> IO Status) -> LuaE e Status
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Status) -> LuaE e Status)
    -> (State -> IO Status) -> LuaE e Status
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      ByteString -> (Ptr CChar -> IO Status) -> IO Status
    forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
    B.useAsCString ByteString
    chunkname ((Ptr CChar -> IO Status) -> IO Status)
    -> (Ptr CChar -> IO Status) -> IO Status
    forall a b. (a -> b) -> a -> b
    $ \Ptr CChar
    namePtr ->
      StatusCode -> Status
    toStatus (StatusCode -> Status) -> IO StatusCode -> IO Status
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State
    -> Reader -> Ptr () -> Ptr CChar -> Ptr CChar -> IO StatusCode
    lua_load State
    l Reader
    reader Ptr ()
    data' Ptr CChar
    namePtr Ptr CChar
    forall a. Ptr a
    nullPtr
    {-# INLINABLE load #-}

    -- | Returns the type of the value in the given valid index, or
    -- @'TypeNone'@ for a non-valid (but acceptable) index.
    --
    -- This function wraps 'lua_type'.
    ltype :: StackIndex -> LuaE e Type
    ltype :: forall e. StackIndex -> LuaE e Type
    ltype StackIndex
    idx = TypeCode -> Type
    toType (TypeCode -> Type) -> LuaE e TypeCode -> LuaE e Type
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> (State -> IO TypeCode) -> LuaE e TypeCode
    forall a e. (State -> IO a) -> LuaE e a
    liftLua (State -> StackIndex -> IO TypeCode
    `lua_type` StackIndex
    idx)
    {-# INLINABLE ltype #-}

    -- | Creates a new empty table and pushes it onto the stack. It is
    -- equivalent to @createtable 0 0@.
    --
    -- See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_newtable lua_newtable>.
    newtable :: LuaE e ()
    newtable :: forall e. LuaE e ()
    newtable = Int -> Int -> LuaE e ()
    forall e. Int -> Int -> LuaE e ()
    createtable Int
    0 Int
    0
    {-# INLINABLE newtable #-}

    -- | This function creates and pushes on the stack a new full userdata,
    -- with @nuvalue@ associated Lua values, called @user values@, plus an
    -- associated block of raw memory with @size@ bytes. (The user values
    -- can be set and read with the functions 'lua_setiuservalue' and
    -- 'lua_getiuservalue'.)
    --
    -- The function returns the address of the block of memory. Lua ensures
    -- that this address is valid as long as the corresponding userdata is
    -- alive (see <https://www.lua.org/manual/5.4/manual.html#2.5 §2.5>).
    -- Moreover, if the userdata is marked for finalization (see
    -- <https://www.lua.org/manual/5.4/manual.html#2.5.3 §2.5.3>), its
    -- address is valid at least until the call to its finalizer.
    --
    -- This function wraps 'lua_newuserdatauv'.
    newuserdatauv :: Int {- ^ size -} -> Int {- ^ nuvalue -} -> LuaE e (Ptr ())
    newuserdatauv :: forall e. Int -> Int -> LuaE e (Ptr ())
    newuserdatauv Int
    size Int
    nuvalue =
      (State -> IO (Ptr ())) -> LuaE e (Ptr ())
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Ptr ())) -> LuaE e (Ptr ()))
    -> (State -> IO (Ptr ())) -> LuaE e (Ptr ())
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> CSize -> CInt -> IO (Ptr ())
    lua_newuserdatauv State
    l (Int -> CSize
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size) (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nuvalue)
    {-# INLINABLE newuserdatauv #-}

    -- | Pops a key from the stack, and pushes a key–value pair from the
    -- table at the given index (the "next" pair after the given key). If
    -- there are no more elements in the table, then @next@ returns @False@
    -- (and pushes nothing).
    --
    -- Errors on the Lua side are caught and rethrown as a @'Exception'@.
    --
    -- This function wraps 'hslua_next'.
    -- See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_next lua_next>.
    next :: LuaError e => StackIndex -> LuaE e Bool
    next :: forall e. LuaError e => StackIndex -> LuaE e Bool
    next StackIndex
    idx = LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> LuaE e LuaBool -> LuaE e Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> (State -> Ptr StatusCode -> IO LuaBool) -> LuaE e LuaBool
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow (\State
    l -> State -> StackIndex -> Ptr StatusCode -> IO LuaBool
    hslua_next State
    l StackIndex
    idx)
    {-# INLINABLE next #-}

    -- | Opens all standard Lua libraries into the current state and sets
    -- each library name as a global value.
    --
    -- This function wraps 'luaL_openlibs'.
    openlibs :: LuaE e ()
    openlibs :: forall e. LuaE e ()
    openlibs = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO ()
    luaL_openlibs
    {-# INLINABLE openlibs #-}

    -- | Pushes Lua's /base/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_base'.
    openbase :: LuaError e => LuaE e ()
    openbase :: forall e. LuaError e => LuaE e ()
    openbase = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_base LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE openbase #-}

    -- | Pushes Lua's /debug/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_io'.
    opendebug :: LuaError e => LuaE e ()
    opendebug :: forall e. LuaError e => LuaE e ()
    opendebug = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_debug LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE opendebug #-}

    -- | Pushes Lua's /io/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_io'.
    openio :: LuaError e => LuaE e ()
    openio :: forall e. LuaError e => LuaE e ()
    openio = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_io LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE openio #-}

    -- | Pushes Lua's /math/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_math'.
    openmath :: LuaError e => LuaE e ()
    openmath :: forall e. LuaError e => LuaE e ()
    openmath = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_math LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE openmath #-}

    -- | Pushes Lua's /os/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_os'.
    openos :: LuaError e => LuaE e ()
    openos :: forall e. LuaError e => LuaE e ()
    openos = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_os LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE openos #-}

    -- | Pushes Lua's /package/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_package'.
    openpackage :: LuaError e => LuaE e ()
    openpackage :: forall e. LuaError e => LuaE e ()
    openpackage = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_package LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE openpackage #-}

    -- | Pushes Lua's /string/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_string'.
    openstring :: LuaError e => LuaE e ()
    openstring :: forall e. LuaError e => LuaE e ()
    openstring = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_string LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE openstring #-}

    -- | Pushes Lua's /table/ library onto the stack.
    --
    -- This function pushes and and calls 'luaopen_table'.
    opentable :: LuaError e => LuaE e ()
    opentable :: forall e. LuaError e => LuaE e ()
    opentable = CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    luaopen_table LuaE e () -> LuaE e () -> LuaE e ()
    forall a b. LuaE e a -> LuaE e b -> LuaE e b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> NumArgs -> NumResults -> LuaE e ()
    forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
    call NumArgs
    0 NumResults
    multret
    {-# INLINABLE opentable #-}

    -- | Calls a function in protected mode.
    --
    -- Both @nargs@ and @nresults@ have the same meaning as in @'call'@. If
    -- there are no errors during the call, @pcall@ behaves exactly like
    -- @'call'@. However, if there is any error, @pcall@ catches it, pushes
    -- a single value on the stack (the error message), and returns the
    -- error code. Like @'call'@, @pcall@ always removes the function and
    -- its arguments from the stack.
    --
    -- If @msgh@ is @Nothing@, then the error object returned on the stack
    -- is exactly the original error object. Otherwise, when @msgh@ is @Just
    -- idx@, the stack index @idx@ is the location of a message handler.
    -- (This index cannot be a pseudo-index.) In case of runtime errors,
    -- this function will be called with the error object and its return
    -- value will be the object returned on the stack by @'pcall'@.
    --
    -- Typically, the message handler is used to add more debug information
    -- to the error object, such as a stack traceback. Such information
    -- cannot be gathered after the return of @'pcall'@, since by then the
    -- stack has unwound.
    --
    -- This function wraps 'lua_pcall'.
    pcall :: NumArgs -> NumResults -> Maybe StackIndex -> LuaE e Status
    pcall :: forall e.
    NumArgs -> NumResults -> Maybe StackIndex -> LuaE e Status
    pcall NumArgs
    nargs NumResults
    nresults Maybe StackIndex
    msgh = (State -> IO Status) -> LuaE e Status
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Status) -> LuaE e Status)
    -> (State -> IO Status) -> LuaE e Status
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      StatusCode -> Status
    toStatus (StatusCode -> Status) -> IO StatusCode -> IO Status
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> NumArgs -> NumResults -> StackIndex -> IO StatusCode
    lua_pcall State
    l NumArgs
    nargs NumResults
    nresults (StackIndex -> Maybe StackIndex -> StackIndex
    forall a. a -> Maybe a -> a
    fromMaybe StackIndex
    0 Maybe StackIndex
    msgh)
    {-# INLINABLE pcall #-}

    -- | Pops @n@ elements from the stack.
    --
    -- See also: <https://www.lua.org/manual/5.4/manual.html#lua_pop lua_pop>.
    pop :: Int -> LuaE e ()
    pop :: forall e. Int -> LuaE e ()
    pop Int
    n = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> CInt -> IO ()
    lua_pop State
    l (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)
    {-# INLINABLE pop #-}

    -- | Pushes a boolean value with the given value onto the stack.
    --
    -- This functions wraps 'lua_pushboolean'.
    pushboolean :: Bool -> LuaE e ()
    pushboolean :: forall e. Bool -> LuaE e ()
    pushboolean Bool
    b = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> LuaBool -> IO ()
    lua_pushboolean State
    l (Bool -> LuaBool
    toLuaBool Bool
    b)
    {-# INLINABLE pushboolean #-}

    -- | Pushes a new C closure onto the stack.
    --
    -- When a C function is created, it is possible to associate some values
    -- with it, thus creating a C closure (see
    -- <https://www.lua.org/manual/5.1/manual.html#3.4 §3.4>); these values
    -- are then accessible to the function whenever it is called. To
    -- associate values with a C function, first these values should be
    -- pushed onto the stack (when there are multiple values, the first
    -- value is pushed first). Then pushcclosure is called to create and
    -- push the C function onto the stack, with the argument @n@ telling how
    -- many values should be associated with the function. pushcclosure also
    -- pops these values from the stack.
    --
    -- The maximum value for @n@ is 255.
    --
    -- Wraps 'lua_pushcclosure'.
    pushcclosure :: CFunction -> NumArgs {- ^ n -} -> LuaE e ()
    pushcclosure :: forall e. CFunction -> NumArgs -> LuaE e ()
    pushcclosure CFunction
    f NumArgs
    n = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> CFunction -> NumArgs -> IO ()
    lua_pushcclosure State
    l CFunction
    f NumArgs
    n
    {-# INLINABLE pushcclosure #-}

    -- | Pushes a C function onto the stack. This function receives a
    -- pointer to a C function and pushes onto the stack a Lua value of type
    -- function that, when called, invokes the corresponding C function.
    --
    -- Any function to be callable by Lua must follow the correct protocol
    -- to receive its parameters and return its results (see @'CFunction'@)
    --
    -- Same as @flip 'pushcclosure' 0@.
    -- <https://www.lua.org/manual/5.4/manual.html#lua_pushcfunction lua_pushcfunction>.
    pushcfunction :: CFunction -> LuaE e ()
    pushcfunction :: forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    f = CFunction -> NumArgs -> LuaE e ()
    forall e. CFunction -> NumArgs -> LuaE e ()
    pushcclosure CFunction
    f NumArgs
    0
    {-# INLINABLE pushcfunction #-}

    -- | Pushes the global environment onto the stack.
    --
    -- Wraps 'lua_pushglobaltable'.
    pushglobaltable :: LuaE e ()
    pushglobaltable :: forall e. LuaE e ()
    pushglobaltable = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO ()
    lua_pushglobaltable
    {-# INLINABLE pushglobaltable #-}

    -- | Pushes an integer with with the given value onto the stack.
    --
    -- Wraps 'lua_pushinteger'.
    pushinteger :: Lua.Integer -> LuaE e ()
    pushinteger :: forall e. Integer -> LuaE e ()
    pushinteger = (State -> Integer -> IO ()) -> Integer -> LuaE e ()
    forall a b e. (State -> a -> IO b) -> a -> LuaE e b
    liftLua1 State -> Integer -> IO ()
    lua_pushinteger
    {-# INLINABLE pushinteger #-}

    -- |  Pushes a light userdata onto the stack.
    --
    -- Userdata represent C values in Lua. A light userdata represents a
    -- pointer, a @Ptr a@ (i.e., @void*@ in C). It is a value (like a
    -- number): you do not create it, it has no individual metatable, and it
    -- is not collected (as it was never created). A light userdata is equal
    -- to "any" light userdata with the same C address.
    --
    -- Wraps 'lua_pushlightuserdata'.
    pushlightuserdata :: Ptr a -> LuaE e ()
    pushlightuserdata :: forall a e. Ptr a -> LuaE e ()
    pushlightuserdata = (State -> Ptr a -> IO ()) -> Ptr a -> LuaE e ()
    forall a b e. (State -> a -> IO b) -> a -> LuaE e b
    liftLua1 State -> Ptr a -> IO ()
    forall a. State -> Ptr a -> IO ()
    lua_pushlightuserdata
    {-# INLINABLE pushlightuserdata #-}

    -- | Pushes a nil value onto the stack.
    --
    -- Wraps 'lua_pushnil'.
    pushnil :: LuaE e ()
    pushnil :: forall e. LuaE e ()
    pushnil = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO ()
    lua_pushnil
    {-# INLINABLE pushnil #-}

    -- | Pushes a float with the given value onto the stack.
    --
    -- Wraps 'lua_pushnumber'.
    pushnumber :: Lua.Number -> LuaE e ()
    pushnumber :: forall e. Number -> LuaE e ()
    pushnumber = (State -> Number -> IO ()) -> Number -> LuaE e ()
    forall a b e. (State -> a -> IO b) -> a -> LuaE e b
    liftLua1 State -> Number -> IO ()
    lua_pushnumber
    {-# INLINABLE pushnumber #-}

    -- | Pushes the string pointed to by s onto the stack. Lua makes (or
    -- reuses) an internal copy of the given string, so the memory at s can
    -- be freed or reused immediately after the function returns.
    --
    -- Wraps 'lua_pushlstring'.
    pushstring :: ByteString -> LuaE e ()
    pushstring :: forall e. ByteString -> LuaE e ()
    pushstring ByteString
    s = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      ByteString -> (CStringLen -> IO ()) -> IO ()
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    B.unsafeUseAsCStringLen ByteString
    s ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \(Ptr CChar
    sPtr, Int
    z) -> State -> Ptr CChar -> CSize -> IO ()
    lua_pushlstring State
    l Ptr CChar
    sPtr (Int -> CSize
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    z)
    {-# INLINABLE pushstring #-}

    -- | Pushes the current thread onto the stack. Returns @True@ if this thread is
    -- the main thread of its state, @False@ otherwise.
    --
    -- Wraps 'lua_pushthread'.
    pushthread :: LuaE e Bool
    pushthread :: forall e. LuaE e Bool
    pushthread = (CInt
    1 CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    ==)  (CInt -> Bool) -> LuaE e CInt -> LuaE e Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> (State -> IO CInt) -> LuaE e CInt
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO CInt
    lua_pushthread
    {-# INLINABLE pushthread #-}

    -- | Pushes a copy of the element at the given index onto the stack.
    --
    -- Wraps 'lua_pushvalue'.
    pushvalue :: StackIndex -> LuaE e ()
    pushvalue :: forall e. StackIndex -> LuaE e ()
    pushvalue StackIndex
    n = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> IO ()
    lua_pushvalue State
    l StackIndex
    n
    {-# INLINABLE pushvalue #-}

    -- | Returns @True@ if the two values in indices @idx1@ and @idx2@ are
    -- primitively equal (that is, without calling the @__eq@ metamethod).
    -- Otherwise returns @False@. Also returns @False@ if any of the indices
    -- are not valid.
    --
    -- Wraps 'lua_rawequal'.
    rawequal :: StackIndex -> StackIndex -> LuaE e Bool
    rawequal :: forall e. StackIndex -> StackIndex -> LuaE e Bool
    rawequal StackIndex
    idx1 StackIndex
    idx2 = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> StackIndex -> IO LuaBool
    lua_rawequal State
    l StackIndex
    idx1 StackIndex
    idx2
    {-# INLINABLE rawequal #-}

    -- | Similar to @'gettable'@, but does a raw access (i.e., without
    -- metamethods).
    --
    -- Wraps 'lua_rawget'.
    rawget :: LuaError e => StackIndex -> LuaE e Type
    rawget :: forall e. LuaError e => StackIndex -> LuaE e Type
    rawget StackIndex
    n = StackIndex -> (State -> IO Type) -> LuaE e Type
    forall e a. LuaError e => StackIndex -> (State -> IO a) -> LuaE e a
    ensureTable StackIndex
    n (\State
    l -> TypeCode -> Type
    toType (TypeCode -> Type) -> IO TypeCode -> IO Type
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO TypeCode
    lua_rawget State
    l StackIndex
    n)
    {-# INLINABLE rawget #-}

    -- | Pushes onto the stack the value @t[n]@, where @t@ is the table at
    -- the given index. The access is raw, that is, it does not invoke the
    -- @__index@ metamethod.
    --
    -- Wraps 'lua_rawgeti'.
    rawgeti :: LuaError e => StackIndex -> Lua.Integer -> LuaE e Type
    rawgeti :: forall e. LuaError e => StackIndex -> Integer -> LuaE e Type
    rawgeti StackIndex
    k Integer
    n = StackIndex -> (State -> IO Type) -> LuaE e Type
    forall e a. LuaError e => StackIndex -> (State -> IO a) -> LuaE e a
    ensureTable StackIndex
    k (\State
    l -> TypeCode -> Type
    toType (TypeCode -> Type) -> IO TypeCode -> IO Type
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> Integer -> IO TypeCode
    lua_rawgeti State
    l StackIndex
    k Integer
    n)
    {-# INLINABLE rawgeti #-}

    -- | Returns the raw "length" of the value at the given index: for
    -- strings, this is the string length; for tables, this is the result of
    -- the length operator (@#@) with no metamethods; for userdata, this is
    -- the size of the block of memory allocated for the userdata; for other
    -- values, it is 0.
    --
    -- Wraps 'lua_rawlen'.
    rawlen :: StackIndex -> LuaE e Int
    rawlen :: forall e. StackIndex -> LuaE e Int
    rawlen StackIndex
    idx = (State -> IO Int) -> LuaE e Int
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Int) -> LuaE e Int)
    -> (State -> IO Int) -> LuaE e Int
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> CSize -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (CSize -> Int) -> IO CSize -> IO Int
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO CSize
    lua_rawlen State
    l StackIndex
    idx
    {-# INLINABLE rawlen #-}

    -- | Similar to @'settable'@, but does a raw assignment (i.e., without
    -- metamethods).
    --
    -- Wraps 'lua_rawset'.
    rawset :: LuaError e => StackIndex -> LuaE e ()
    rawset :: forall e. LuaError e => StackIndex -> LuaE e ()
    rawset StackIndex
    n = StackIndex -> (State -> IO ()) -> LuaE e ()
    forall e a. LuaError e => StackIndex -> (State -> IO a) -> LuaE e a
    ensureTable StackIndex
    n (\State
    l -> State -> StackIndex -> IO ()
    lua_rawset State
    l StackIndex
    n)
    {-# INLINABLE rawset #-}

    -- | Does the equivalent of @t[i] = v@, where @t@ is the table at the given
    -- index and @v@ is the value at the top of the stack.
    --
    -- This function pops the value from the stack. The assignment is raw, that is,
    -- it does not invoke the @__newindex@ metamethod.
    --
    -- Wraps 'lua_rawseti'.
    rawseti :: LuaError e => StackIndex -> Lua.Integer -> LuaE e ()
    rawseti :: forall e. LuaError e => StackIndex -> Integer -> LuaE e ()
    rawseti StackIndex
    k Integer
    m = StackIndex -> (State -> IO ()) -> LuaE e ()
    forall e a. LuaError e => StackIndex -> (State -> IO a) -> LuaE e a
    ensureTable StackIndex
    k (\State
    l -> State -> StackIndex -> Integer -> IO ()
    lua_rawseti State
    l StackIndex
    k Integer
    m)
    {-# INLINABLE rawseti #-}

    -- | Sets the C function @f@ as the new value of global @name@.
    --
    -- Behaves like "lua_register".
    register :: LuaError e => Name -> CFunction -> LuaE e ()
    register :: forall e. LuaError e => Name -> CFunction -> LuaE e ()
    register Name
    name CFunction
    f = do
      CFunction -> LuaE e ()
    forall e. CFunction -> LuaE e ()
    pushcfunction CFunction
    f
      Name -> LuaE e ()
    forall e. LuaError e => Name -> LuaE e ()
    setglobal Name
    name
    {-# INLINABLE register #-}

    -- | Removes the element at the given valid index, shifting down the
    -- elements above this index to fill the gap. This function cannot be
    -- called with a pseudo-index, because a pseudo-index is not an actual
    -- stack position.
    --
    -- Wraps 'lua_remove'.
    remove :: StackIndex -> LuaE e ()
    remove :: forall e. StackIndex -> LuaE e ()
    remove StackIndex
    n = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> IO ()
    lua_remove State
    l StackIndex
    n
    {-# INLINABLE remove #-}

    -- | Moves the top element into the given valid index without shifting
    -- any element (therefore replacing the value at that given index), and
    -- then pops the top element.
    --
    -- Wraps 'lua_replace'.
    replace :: StackIndex -> LuaE e ()
    replace :: forall e. StackIndex -> LuaE e ()
    replace StackIndex
    n = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->  State -> StackIndex -> IO ()
    lua_replace State
    l StackIndex
    n
    {-# INLINABLE replace #-}

    -- | Rotates the stack elements between the valid index @idx@ and the
    -- top of the stack. The elements are rotated @n@ positions in the
    -- direction of the top, for a positive @n@, or @-n@ positions in the
    -- direction of the bottom, for a negative @n@. The absolute value of
    -- @n@ must not be greater than the size of the slice being rotated.
    -- This function cannot be called with a pseudo-index, because a
    -- pseudo-index is not an actual stack position.
    --
    -- <https://www.lua.org/manual/5.4/manual.html#lua_rotate>
    rotate :: StackIndex  -- ^ @idx@
           -> Int         -- ^ @n@
           -> LuaE e ()
    rotate :: forall e. StackIndex -> Int -> LuaE e ()
    rotate StackIndex
    idx Int
    n = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> CInt -> IO ()
    lua_rotate State
    l StackIndex
    idx (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)
    {-# INLINABLE rotate #-}

    -- | Does the equivalent to @t[k] = v@, where @t@ is the value at the
    -- given index and @v@ is the value at the top of the stack.
    --
    -- This function pops the value from the stack. As in Lua, this function
    -- may trigger a metamethod for the "newindex" event (see
    -- <https://www.lua.org/manual/5.4/manual.html#2.4 §2.4> of the Lua 5.4
    -- Reference Manual).
    --
    -- Errors on the Lua side are caught and rethrown as a @'Exception'@.
    --
    -- See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_setfield lua_setfield>.
    setfield :: LuaError e => StackIndex -> Name -> LuaE e ()
    setfield :: forall e. LuaError e => StackIndex -> Name -> LuaE e ()
    setfield StackIndex
    i (Name ByteString
    s) = do
      absidx <- StackIndex -> LuaE e StackIndex
    forall e. StackIndex -> LuaE e StackIndex
    absindex StackIndex
    i
      pushstring s
      insert (nthTop 2)
      settable absidx
    {-# INLINABLE setfield #-}

    -- | Pops a value from the stack and sets it as the new value of global
    -- @name@.
    --
    -- Errors on the Lua side are caught and rethrown as 'Exception'.
    --
    -- Wraps 'hslua_setglobal'. See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_setglobal lua_setglobal>.
    setglobal :: LuaError e => Name {- ^ name -} -> LuaE e ()
    setglobal :: forall e. LuaError e => Name -> LuaE e ()
    setglobal (Name ByteString
    name) = (State -> Ptr StatusCode -> IO ()) -> LuaE e ()
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow ((State -> Ptr StatusCode -> IO ()) -> LuaE e ())
    -> (State -> Ptr StatusCode -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l Ptr StatusCode
    status' ->
      ByteString -> (CStringLen -> IO ()) -> IO ()
    forall a. ByteString -> (CStringLen -> IO a) -> IO a
    B.unsafeUseAsCStringLen ByteString
    name ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \(Ptr CChar
    namePtr, Int
    nameLen) ->
        State -> Ptr CChar -> CSize -> Ptr StatusCode -> IO ()
    hslua_setglobal State
    l Ptr CChar
    namePtr (Int -> CSize
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nameLen) Ptr StatusCode
    status'
    {-# INLINABLE setglobal #-}

    -- | Pops a table from the stack and sets it as the new metatable for
    -- the value at the given index.
    --
    -- Wraps 'lua_setmetatable'.
    setmetatable :: StackIndex -> LuaE e ()
    setmetatable :: forall e. StackIndex -> LuaE e ()
    setmetatable StackIndex
    idx = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> IO ()
    lua_setmetatable State
    l StackIndex
    idx
    {-# INLINABLE setmetatable #-}

    -- | Does the equivalent to @t[k] = v@, where @t@ is the value at the
    -- given index, @v@ is the value at the top of the stack, and @k@ is the
    -- value just below the top.
    --
    -- This function pops both the key and the value from the stack. As in
    -- Lua, this function may trigger a metamethod for the "newindex" event
    -- (see <https://www.lua.org/manual/5.4/manual.html#2.4 §2.4> of the Lua
    -- 5.4 Reference Manual).
    --
    -- Errors on the Lua side are caught and rethrown.
    --
    -- Wraps 'hslua_settable'.
    settable :: LuaError e => StackIndex -> LuaE e ()
    settable :: forall e. LuaError e => StackIndex -> LuaE e ()
    settable StackIndex
    index = (State -> Ptr StatusCode -> IO ()) -> LuaE e ()
    forall e a.
    LuaError e =>
    (State -> Ptr StatusCode -> IO a) -> LuaE e a
    liftLuaThrow ((State -> Ptr StatusCode -> IO ()) -> LuaE e ())
    -> (State -> Ptr StatusCode -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> Ptr StatusCode -> IO ()
    hslua_settable State
    l StackIndex
    index
    {-# INLINABLE settable #-}

    -- | Accepts any index, or 0, and sets the stack top to this index. If
    -- the new top is larger than the old one, then the new elements are
    -- filled with nil. If index is 0, then all stack elements are removed.
    --
    -- Wraps 'lua_settop'.
    settop :: StackIndex -> LuaE e ()
    settop :: forall e. StackIndex -> LuaE e ()
    settop = (State -> StackIndex -> IO ()) -> StackIndex -> LuaE e ()
    forall a b e. (State -> a -> IO b) -> a -> LuaE e b
    liftLua1 State -> StackIndex -> IO ()
    lua_settop
    {-# INLINABLE settop #-}

    -- | Pops a value from the stack and sets it as the new @n@-th user
    -- value associated to the full userdata at the given index. Returns 0
    -- if the userdata does not have that value.
    --
    -- Wraps 'lua_setiuservalue'.
    setiuservalue :: StackIndex {- ^ index -} -> Int {- ^ n -} -> LuaE e Bool
    setiuservalue :: forall e. StackIndex -> Int -> LuaE e Bool
    setiuservalue StackIndex
    idx Int
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> CInt -> IO LuaBool
    lua_setiuservalue State
    l StackIndex
    idx (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n)

    -- | Sets the warning function to be used by Lua to emit warnings (see
    -- 'WarnFunction'). The @ud@ parameter sets the value @ud@ passed to the
    -- warning function.
    setwarnf :: WarnFunction -- ^ f
             -> Ptr ()       -- ^ ud
             -> LuaE e ()
    setwarnf :: forall e. WarnFunction -> Ptr () -> LuaE e ()
    setwarnf WarnFunction
    f Ptr ()
    ud = (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ()) -> LuaE e ()) -> (State -> IO ()) -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      State -> WarnFunction -> Ptr () -> IO ()
    lua_setwarnf State
    l WarnFunction
    f Ptr ()
    ud

    -- |  Returns the status of this Lua thread.
    --
    -- The status can be 'OK' for a normal thread, an error value if the
    -- thread finished the execution of a @lua_resume@ with an error, or
    -- 'Yield' if the thread is suspended.
    --
    -- You can only call functions in threads with status 'OK'. You can
    -- resume threads with status 'OK' (to start a new coroutine) or 'Yield'
    -- (to resume a coroutine).
    --
    -- Wraps 'lua_status'.
    status :: LuaE e Status
    status :: forall e. LuaE e Status
    status = (State -> IO Status) -> LuaE e Status
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Status) -> LuaE e Status)
    -> (State -> IO Status) -> LuaE e Status
    forall a b. (a -> b) -> a -> b
    $ (StatusCode -> Status) -> IO StatusCode -> IO Status
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap StatusCode -> Status
    toStatus (IO StatusCode -> IO Status)
    -> (State -> IO StatusCode) -> State -> IO Status
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . State -> IO StatusCode
    lua_status
    {-# INLINABLE status #-}

    -- | Converts the Lua value at the given index to a haskell boolean
    -- value. Like all tests in Lua, @toboolean@ returns @True@ for any Lua
    -- value different from @false@ and @nil@; otherwise it returns @False@.
    -- (If you want to accept only actual boolean values, use @'isboolean'@
    -- to test the value's type.)
    --
    -- Wraps 'lua_toboolean'.
    toboolean :: StackIndex -> LuaE e Bool
    toboolean :: forall e. StackIndex -> LuaE e Bool
    toboolean StackIndex
    n = (State -> IO Bool) -> LuaE e Bool
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO Bool) -> LuaE e Bool)
    -> (State -> IO Bool) -> LuaE e Bool
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> LuaBool -> Bool
    fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
    forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
    <$!> State -> StackIndex -> IO LuaBool
    lua_toboolean State
    l StackIndex
    n
    {-# INLINABLE toboolean #-}

    -- | Converts a value at the given index to a C function. That value
    -- must be a C function; otherwise, returns @Nothing@.
    --
    -- Wraps 'lua_tocfunction'.
    tocfunction :: StackIndex -> LuaE e (Maybe CFunction)
    tocfunction :: forall e. StackIndex -> LuaE e (Maybe CFunction)
    tocfunction StackIndex
    n = (State -> IO (Maybe CFunction)) -> LuaE e (Maybe CFunction)
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Maybe CFunction)) -> LuaE e (Maybe CFunction))
    -> (State -> IO (Maybe CFunction)) -> LuaE e (Maybe CFunction)
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> do
      fnPtr <- State -> StackIndex -> IO CFunction
    lua_tocfunction State
    l StackIndex
    n
      return (if fnPtr == nullFunPtr then Nothing else Just fnPtr)
    {-# INLINABLE tocfunction #-}

    -- | Converts the Lua value at the given acceptable index to the signed
    -- integral type 'Lua.Integer'. The Lua value must be an integer, a
    -- number or a string convertible to an integer (see
    -- <https://www.lua.org/manual/5.4/manual.html#3.4.3 §3.4.3> of the Lua
    -- 5.4 Reference Manual); otherwise, @tointeger@ returns @Nothing@.
    --
    -- If the number is not an integer, it is truncated in some
    -- non-specified way.
    --
    -- Wraps 'lua_tointegerx'. See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_tointeger lua_tointeger>.
    tointeger :: StackIndex -> LuaE e (Maybe Lua.Integer)
    tointeger :: forall e. StackIndex -> LuaE e (Maybe Integer)
    tointeger StackIndex
    n = (State -> IO (Maybe Integer)) -> LuaE e (Maybe Integer)
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Maybe Integer)) -> LuaE e (Maybe Integer))
    -> (State -> IO (Maybe Integer)) -> LuaE e (Maybe Integer)
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> (Ptr LuaBool -> IO (Maybe Integer)) -> IO (Maybe Integer)
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr LuaBool -> IO (Maybe Integer)) -> IO (Maybe Integer))
    -> (Ptr LuaBool -> IO (Maybe Integer)) -> IO (Maybe Integer)
    forall a b. (a -> b) -> a -> b
    $ \Ptr LuaBool
    boolPtr -> do
      res <- State -> StackIndex -> Ptr LuaBool -> IO Integer
    lua_tointegerx State
    l StackIndex
    n Ptr LuaBool
    boolPtr
      isNum <- fromLuaBool <$!> F.peek boolPtr
      return (if isNum then Just res else Nothing)
    {-# INLINABLE tointeger #-}

    -- | Converts the Lua value at the given index to a 'Lua.Number'. The
    -- Lua value must be a number or a string convertible to a number;
    -- otherwise, @tonumber@ returns @'Nothing'@.
    --
    -- Wraps 'lua_tonumberx'. See also
    -- <https://www.lua.org/manual/5.4/manual.html#lua_tonumber lua_tonumber>.
    tonumber :: StackIndex -> LuaE e (Maybe Lua.Number)
    tonumber :: forall e. StackIndex -> LuaE e (Maybe Number)
    tonumber StackIndex
    n = (State -> IO (Maybe Number)) -> LuaE e (Maybe Number)
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Maybe Number)) -> LuaE e (Maybe Number))
    -> (State -> IO (Maybe Number)) -> LuaE e (Maybe Number)
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> (Ptr LuaBool -> IO (Maybe Number)) -> IO (Maybe Number)
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr LuaBool -> IO (Maybe Number)) -> IO (Maybe Number))
    -> (Ptr LuaBool -> IO (Maybe Number)) -> IO (Maybe Number)
    forall a b. (a -> b) -> a -> b
    $ \Ptr LuaBool
    bptr -> do
      res <- State -> StackIndex -> Ptr LuaBool -> IO Number
    lua_tonumberx State
    l StackIndex
    n Ptr LuaBool
    bptr
      isNum <- fromLuaBool <$!> F.peek bptr
      return (if isNum then Just res else Nothing)
    {-# INLINABLE tonumber #-}

    -- | Converts the value at the given index to a generic C pointer
    -- (void*). The value can be a userdata, a table, a thread, or a
    -- function; otherwise, lua_topointer returns @nullPtr@. Different
    -- objects will give different pointers. There is no way to convert the
    -- pointer back to its original value.
    --
    -- Typically this function is used only for hashing and debug
    -- information.
    --
    -- Wraps 'lua_topointer'.
    topointer :: StackIndex -> LuaE e (Ptr ())
    topointer :: forall e. StackIndex -> LuaE e (Ptr ())
    topointer StackIndex
    n = (State -> IO (Ptr ())) -> LuaE e (Ptr ())
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Ptr ())) -> LuaE e (Ptr ()))
    -> (State -> IO (Ptr ())) -> LuaE e (Ptr ())
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> State -> StackIndex -> IO (Ptr ())
    lua_topointer State
    l StackIndex
    n
    {-# INLINABLE topointer #-}

    -- | Converts the Lua value at the given index to a 'ByteString'. The
    -- Lua value must be a string or a number; otherwise, the function
    -- returns 'Nothing'. If the value is a number, then 'tostring' also
    -- changes the actual value in the stack to a string. (This change
    -- confuses 'next' when 'tostring' is applied to keys during a table
    -- traversal.)
    --
    -- Wraps 'lua_tolstring'.
    tostring :: StackIndex -> LuaE e (Maybe ByteString)
    tostring :: forall e. StackIndex -> LuaE e (Maybe ByteString)
    tostring StackIndex
    n = (State -> IO (Maybe ByteString)) -> LuaE e (Maybe ByteString)
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Maybe ByteString)) -> LuaE e (Maybe ByteString))
    -> (State -> IO (Maybe ByteString)) -> LuaE e (Maybe ByteString)
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      (Ptr CSize -> IO (Maybe ByteString)) -> IO (Maybe ByteString)
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr CSize -> IO (Maybe ByteString)) -> IO (Maybe ByteString))
    -> (Ptr CSize -> IO (Maybe ByteString)) -> IO (Maybe ByteString)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CSize
    lenPtr -> do
        cstr <- State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
    lua_tolstring State
    l StackIndex
    n Ptr CSize
    lenPtr
        if cstr == nullPtr
          then return Nothing
          else do
          cstrLen <- F.peek lenPtr
          Just <$!> B.packCStringLen (cstr, fromIntegral cstrLen)
    {-# INLINABLE tostring #-}

    -- | Converts the value at the given index to a Lua thread (represented
    -- as 'Lua.State'). This value must be a thread; otherwise, the function
    -- returns @Nothing@.
    --
    -- Wraps 'lua_tothread'.
    tothread :: StackIndex -> LuaE e (Maybe Lua.State)
    tothread :: forall e. StackIndex -> LuaE e (Maybe State)
    tothread StackIndex
    n = (State -> IO (Maybe State)) -> LuaE e (Maybe State)
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Maybe State)) -> LuaE e (Maybe State))
    -> (State -> IO (Maybe State)) -> LuaE e (Maybe State)
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> do
      thread@(Lua.State ptr) <- State -> StackIndex -> IO State
    lua_tothread State
    l StackIndex
    n
      if ptr == nullPtr
        then return Nothing
        else return (Just thread)
    {-# INLINABLE tothread #-}

    -- | If the value at the given index is a full userdata, returns its
    -- block address. If the value is a light userdata, returns its pointer.
    -- Otherwise, returns @Nothing@..
    --
    -- Wraps 'lua_touserdata'.
    touserdata :: StackIndex -> LuaE e (Maybe (Ptr a))
    touserdata :: forall e a. StackIndex -> LuaE e (Maybe (Ptr a))
    touserdata StackIndex
    n = (State -> IO (Maybe (Ptr a))) -> LuaE e (Maybe (Ptr a))
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO (Maybe (Ptr a))) -> LuaE e (Maybe (Ptr a)))
    -> (State -> IO (Maybe (Ptr a))) -> LuaE e (Maybe (Ptr a))
    forall a b. (a -> b) -> a -> b
    $ \State
    l -> do
      ptr <- State -> StackIndex -> IO (Ptr a)
    forall a. State -> StackIndex -> IO (Ptr a)
    lua_touserdata State
    l StackIndex
    n
      if ptr == nullPtr
        then return Nothing
        else return (Just ptr)
    {-# INLINABLE touserdata #-}

    -- | Returns the name of the type encoded by the value @tp@, which must
    -- be one the values returned by @'ltype'@.
    --
    -- Wraps 'lua_typename'.
    typename :: Type -> LuaE e ByteString
    typename :: forall e. Type -> LuaE e ByteString
    typename Type
    tp = (State -> IO ByteString) -> LuaE e ByteString
    forall a e. (State -> IO a) -> LuaE e a
    liftLua ((State -> IO ByteString) -> LuaE e ByteString)
    -> (State -> IO ByteString) -> LuaE e ByteString
    forall a b. (a -> b) -> a -> b
    $ \State
    l ->
      State -> TypeCode -> IO (Ptr CChar)
    lua_typename State
    l (Type -> TypeCode
    fromType Type
    tp) IO (Ptr CChar) -> (Ptr CChar -> IO ByteString) -> IO ByteString
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Ptr CChar -> IO ByteString
    B.packCString
    {-# INLINABLE typename #-}

    -- | Returns the pseudo-index that represents the @i@-th upvalue of the
    -- running function (see <https://www.lua.org/manual/5.4/manual.html#4.2
    -- §4.2> of the Lua 5.4 reference manual).
    --
    -- See also:
    -- <https://www.lua.org/manual/5.4/manual.html#lua_upvalueindex lua_upvalueindex>.
    upvalueindex :: StackIndex -> StackIndex
    upvalueindex :: StackIndex -> StackIndex
    upvalueindex StackIndex
    i = StackIndex
    registryindex StackIndex -> StackIndex -> StackIndex
    forall a. Num a => a -> a -> a
    - StackIndex
    i
    {-# INLINABLE upvalueindex #-}