{-|
Module      : Foreign.Lua.Core.Functions
Copyright   : © 2007–2012 Gracjan Polak,
                2012–2016 Ömer Sinan Ağacan,
                2017-2020 Albert Krewinkel
License     : MIT
Maintainer  : Albert Krewinkel <tarleb+hslua@zeitkraut.de>
Stability   : beta
Portability : non-portable (depends on GHC)

Monadic functions which operate within the Lua type.

The functions in this module are mostly just 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'@. Memory allocation errors,
however, are not caught and will cause the host program to terminate.
-}
module Foreign.Lua.Core.Functions where

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

import Control.Monad
import Data.ByteString (ByteString)
import Data.Maybe (fromMaybe)
import Foreign.Lua.Core.Constants
import Foreign.Lua.Core.Error
import Foreign.Lua.Core.RawBindings
import Foreign.Lua.Core.Types as 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.C as C
import qualified Foreign.Lua.Utf8 as Utf8
import qualified Foreign.Storable as F

--
-- Helper functions
--

-- | Execute an action only if the given index is a table. Throw an
-- error otherwise.
ensureTable :: StackIndex -> (Lua.State -> IO ()) -> Lua ()
ensureTable :: StackIndex -> (State -> IO ()) -> Lua ()
ensureTable StackIndex
idx State -> IO ()
ioOp = do
  Bool
isTbl <- StackIndex -> Lua Bool
istable StackIndex
idx
  if Bool
isTbl
    then (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua State -> IO ()
ioOp
    else do
      String
tyName <- StackIndex -> Lua Type
ltype StackIndex
idx Lua Type -> (Type -> Lua String) -> Lua String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Type -> Lua String
typename
      String -> Lua ()
forall a. String -> Lua a
throwMessage (String
"table expected, got " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
tyName)

--
-- API functions
--

-- | Converts the acceptable index @idx@ into an equivalent absolute index (that
-- is, one that does not depend on the stack top).
absindex :: StackIndex -> Lua StackIndex
absindex :: StackIndex -> Lua StackIndex
absindex = (State -> StackIndex -> IO StackIndex)
-> StackIndex -> Lua StackIndex
forall a b. (State -> a -> IO b) -> a -> Lua b
liftLua1 State -> StackIndex -> IO StackIndex
lua_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 cause a @'Exception'@ to be thrown.
--
-- 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.3/manual.html#lua_call lua_call>.
call :: NumArgs -> NumResults -> Lua ()
call :: NumArgs -> NumResults -> Lua ()
call NumArgs
nargs NumResults
nresults = do
  Status
res <- NumArgs -> NumResults -> Maybe StackIndex -> Lua Status
pcall NumArgs
nargs NumResults
nresults Maybe StackIndex
forall a. Maybe a
Nothing
  Bool -> Lua () -> Lua ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Status
res Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
/= Status
OK) Lua ()
forall a. Lua a
throwTopMessage

-- | 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.
--
-- This is a wrapper function of
-- <https://www.lua.org/manual/5.3/manual.html#lua_checkstack lua_checkstack>.
checkstack :: Int -> Lua Bool
checkstack :: Int -> Lua Bool
checkstack Int
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> CInt -> IO LuaBool
lua_checkstack State
l (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)

-- | 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.
--
-- This is a wrapper function of
-- <https://www.lua.org/manual/5.3/manual.html#lua_close lua_close>.
close :: Lua.State -> IO ()
close :: State -> IO ()
close = State -> IO ()
lua_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 (<=)
--
-- This is a wrapper function of
-- <https://www.lua.org/manual/5.3/manual.html#lua_compare lua_compare>.
compare :: StackIndex -> StackIndex -> RelationalOperator -> Lua Bool
compare :: StackIndex -> StackIndex -> RelationalOperator -> Lua Bool
compare StackIndex
idx1 StackIndex
idx2 RelationalOperator
relOp = LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> Lua LuaBool -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
  (State -> Ptr StatusCode -> IO LuaBool) -> Lua LuaBool
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow ((State -> Ptr StatusCode -> IO LuaBool) -> Lua LuaBool)
-> (State -> Ptr StatusCode -> IO LuaBool) -> Lua LuaBool
forall a b. (a -> b) -> a -> b
$ \State
l -> State
-> StackIndex -> StackIndex -> CInt -> Ptr StatusCode -> IO LuaBool
hslua_compare State
l StackIndex
idx1 StackIndex
idx2 (RelationalOperator -> CInt
fromRelationalOperator RelationalOperator
relOp)

-- | 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.3/manual.html#3.4.6 §3.4.6> of the lua
-- manual).
--
-- This is a wrapper function of
-- <https://www.lua.org/manual/5.3/manual.html#lua_concat lua_concat>.
concat :: NumArgs -> Lua ()
concat :: NumArgs -> Lua ()
concat NumArgs
n = (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow (State -> NumArgs -> Ptr StatusCode -> IO ()
`hslua_concat` NumArgs
n)

-- | Copies the element at index @fromidx@ into the valid index @toidx@,
-- replacing the value at that position. Values at other positions are not
-- affected.
--
-- See also <https://www.lua.org/manual/5.3/manual.html#lua_copy lua_copy> in
-- the lua manual.
copy :: StackIndex -> StackIndex -> Lua ()
copy :: StackIndex -> StackIndex -> Lua ()
copy StackIndex
fromidx StackIndex
toidx = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> StackIndex -> IO ()
lua_copy State
l StackIndex
fromidx StackIndex
toidx

-- | 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.
--
-- This is a wrapper for function
-- <https://www.lua.org/manual/5.3/manual.html#lua_createtable lua_createtable>.
createtable :: Int -> Int -> Lua ()
createtable :: Int -> Int -> Lua ()
createtable Int
narr Int
nrec = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
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)

-- 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 :: StackIndex  -- ^ index1
      -> StackIndex  -- ^ index2
      -> Lua Bool
equal :: StackIndex -> StackIndex -> Lua Bool
equal StackIndex
index1 StackIndex
index2 = StackIndex -> StackIndex -> RelationalOperator -> Lua Bool
compare StackIndex
index1 StackIndex
index2 RelationalOperator
EQ

-- | This is a convenience function to implement error propagation
-- convention described in [Error handling in hslua](#g:1). hslua
-- doesn't implement the @lua_error@ function from Lua C API because
-- it's never safe to use. (see [Error handling in hslua](#g:1) for
-- details)
error :: Lua NumResults
error :: Lua NumResults
error = (State -> IO NumResults) -> Lua NumResults
forall a. (State -> IO a) -> Lua a
liftLua State -> IO NumResults
hslua_error

-- |  Controls the garbage collector.
--
-- This function performs several tasks, according to the value of the parameter
-- what:
--
--   * @'GCSTOP'@: stops the garbage collector.
--
--   * @'GCRESTART'@: restarts the garbage collector.
--
--   * @'GCCOLLECT'@: performs a full garbage-collection cycle.
--
--   * @'GCCOUNT'@: returns the current amount of memory (in Kbytes) in use by
--     Lua.
--
--   * @'GCCOUNTB'@: returns the remainder of dividing the current amount of
--     bytes of memory in use by Lua by 1024.
--
--   * @'GCSTEP'@: performs an incremental step of garbage collection. The step
--     "size" is controlled by data (larger values mean more steps) in a
--     non-specified way. If you want to control the step size you must
--     experimentally tune the value of data. The function returns 1 if the step
--     finished a garbage-collection cycle.
--
--   * @'GCSETPAUSE@': sets data as the new value for the pause of the collector
--     (see §2.10). The function returns the previous value of the pause.
--
--   * @'GCSETSTEPMUL'@: sets data as the new value for the step multiplier of
--     the collector (see §2.10). The function returns the previous value of the
--     step multiplier.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_gc lua_gc>.
gc :: GCCONTROL -> Int -> Lua Int
gc :: GCCONTROL -> Int -> Lua Int
gc GCCONTROL
what Int
data' = (State -> IO Int) -> Lua Int
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Int) -> Lua Int) -> (State -> IO Int) -> Lua Int
forall a b. (a -> b) -> a -> b
$ \State
l ->
  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
<$> State -> CInt -> CInt -> IO CInt
lua_gc State
l (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (GCCONTROL -> Int
forall a. Enum a => a -> Int
fromEnum GCCONTROL
what)) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
data')

-- | 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.3/manual.html#2.4 §2.4> of
-- lua's manual).
--
-- Errors on the Lua side are caught and rethrown as @'Exception'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_getfield lua_getfield>.
getfield :: StackIndex -> String -> Lua ()
getfield :: StackIndex -> String -> Lua ()
getfield StackIndex
i String
s = do
  StackIndex
absidx <- StackIndex -> Lua StackIndex
absindex StackIndex
i
  ByteString -> Lua ()
pushstring (String -> ByteString
Utf8.fromString String
s)
  StackIndex -> Lua ()
gettable StackIndex
absidx

-- | Pushes onto the stack the value of the global @name@.
--
-- Errors on the Lua side are caught and rethrown as @'Exception'@.
--
-- Wrapper of
-- <https://www.lua.org/manual/5.3/manual.html#lua_getglobal lua_getglobal>.
getglobal :: String -> Lua ()
getglobal :: String -> Lua ()
getglobal String
name = (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow ((State -> Ptr StatusCode -> IO ()) -> Lua ())
-> (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l Ptr StatusCode
status' ->
  String -> (CStringLen -> IO ()) -> IO ()
forall a. String -> (CStringLen -> IO a) -> IO a
C.withCStringLen String
name ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
namePtr, Int
len) ->
  State -> Ptr CChar -> CSize -> Ptr StatusCode -> IO ()
hslua_getglobal State
l Ptr CChar
namePtr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) Ptr StatusCode
status'

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_getmetatable lua_getmetatable>.
getmetatable :: StackIndex -> Lua Bool
getmetatable :: StackIndex -> Lua Bool
getmetatable StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l ->
  LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_getmetatable State
l StackIndex
n

-- | 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.3/manual.html#2.4 §2.4> of lua's
-- manual).
--
-- Errors on the Lua side are caught and rethrown as @'Exception'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_gettable lua_gettable>.
gettable :: StackIndex -> Lua ()
gettable :: StackIndex -> Lua ()
gettable StackIndex
n = (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow (\State
l -> State -> StackIndex -> Ptr StatusCode -> IO ()
hslua_gettable State
l StackIndex
n)

-- | 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).
--
-- See also: <https://www.lua.org/manual/5.3/manual.html#lua_gettop lua_gettop>.
gettop :: Lua StackIndex
gettop :: Lua StackIndex
gettop = (State -> IO StackIndex) -> Lua StackIndex
forall a. (State -> IO a) -> Lua a
liftLua State -> IO StackIndex
lua_gettop

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_insert lua_insert>.
insert :: StackIndex -> Lua ()
insert :: StackIndex -> Lua ()
insert StackIndex
index = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> IO ()
lua_insert State
l StackIndex
index

-- | Returns @True@ if the value at the given index is a boolean, and @False@
-- otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isboolean lua_isboolean>.
isboolean :: StackIndex -> Lua Bool
isboolean :: StackIndex -> Lua Bool
isboolean StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeBoolean) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | Returns @True@ if the value at the given index is a C function, and @False@
-- otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_iscfunction lua_iscfunction>.
iscfunction :: StackIndex -> Lua Bool
iscfunction :: StackIndex -> Lua Bool
iscfunction StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_iscfunction State
l StackIndex
n

-- | Returns @True@ if the value at the given index is a function (either C or
-- Lua), and @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isfunction lua_isfunction>.
isfunction :: StackIndex -> Lua Bool
isfunction :: StackIndex -> Lua Bool
isfunction StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeFunction) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | 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.
isinteger :: StackIndex -> Lua Bool
isinteger :: StackIndex -> Lua Bool
isinteger StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_isinteger State
l StackIndex
n

-- | Returns @True@ if the value at the given index is a light userdata, and
-- @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_islightuserdata \
-- lua_islightuserdata>.
islightuserdata :: StackIndex -> Lua Bool
islightuserdata :: StackIndex -> Lua Bool
islightuserdata StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeLightUserdata) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | Returns @True@ if the value at the given index is @nil@, and @False@
-- otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isnil lua_isnil>.
isnil :: StackIndex -> Lua Bool
isnil :: StackIndex -> Lua Bool
isnil StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeNil) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | Returns @True@ if the given index is not valid, and @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isnone lua_isnone>.
isnone :: StackIndex -> Lua Bool
isnone :: StackIndex -> Lua Bool
isnone StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeNone) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | Returns @True@ if the given index is not valid or if the value at the given
-- index is @nil@, and @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isnoneornil lua_isnoneornil>.
isnoneornil :: StackIndex -> Lua Bool
isnoneornil :: StackIndex -> Lua Bool
isnoneornil StackIndex
idx = (Type -> Type -> Bool
forall a. Ord a => a -> a -> Bool
<= Type
TypeNil) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
idx

-- | Returns @True@ if the value at the given index is a number or a string
-- convertible to a number, and @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isnumber lua_isnumber>.
isnumber :: StackIndex -> Lua Bool
isnumber :: StackIndex -> Lua Bool
isnumber StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_isnumber State
l StackIndex
n

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isstring lua_isstring>.
isstring :: StackIndex -> Lua Bool
isstring :: StackIndex -> Lua Bool
isstring StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_isstring State
l StackIndex
n

-- | Returns @True@ if the value at the given index is a table, and @False@
-- otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_istable lua_istable>.
istable :: StackIndex -> Lua Bool
istable :: StackIndex -> Lua Bool
istable StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeTable) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | Returns @True@ if the value at the given index is a thread, and @False@
-- otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isthread lua_isthread>.
isthread :: StackIndex -> Lua Bool
isthread :: StackIndex -> Lua Bool
isthread StackIndex
n = (Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
TypeThread) (Type -> Bool) -> Lua Type -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Type
ltype StackIndex
n

-- | Returns @True@ if the value at the given index is a userdata (either full
-- or light), and @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_isuserdata lua_isuserdata>.
isuserdata :: StackIndex -> Lua Bool
isuserdata :: StackIndex -> Lua Bool
isuserdata StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_isuserdata State
l StackIndex
n

-- | Tests whether the object under the first index is smaller than that under
-- the second. Uses @'compare'@ internally.
lessthan :: StackIndex -> StackIndex -> Lua Bool
lessthan :: StackIndex -> StackIndex -> Lua Bool
lessthan StackIndex
index1 StackIndex
index2 = StackIndex -> StackIndex -> RelationalOperator -> Lua Bool
compare StackIndex
index1 StackIndex
index2 RelationalOperator
LT

-- | 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.3/manual.html#4.9 §4.9>). Note that the
-- @chunkname@ is used as a C string, so it may not contain null-bytes.
load :: Lua.Reader -> Ptr () -> ByteString -> Lua Status
load :: Reader -> Ptr () -> ByteString -> Lua Status
load Reader
reader Ptr ()
data' ByteString
chunkname = (State -> IO Status) -> Lua Status
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Status) -> Lua Status)
-> (State -> IO Status) -> Lua 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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f 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

-- | Returns the type of the value in the given valid index, or @'TypeNone'@ for
-- a non-valid (but acceptable) index.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_type lua_type>.
ltype :: StackIndex -> Lua Type
ltype :: StackIndex -> Lua Type
ltype StackIndex
idx = TypeCode -> Type
toType (TypeCode -> Type) -> Lua TypeCode -> Lua Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (State -> IO TypeCode) -> Lua TypeCode
forall a. (State -> IO a) -> Lua a
liftLua (State -> StackIndex -> IO TypeCode
`lua_type` StackIndex
idx)

-- | 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.3/manual.html#lua_newtable lua_newtable>.
newtable :: Lua ()
newtable :: Lua ()
newtable = Int -> Int -> Lua ()
createtable Int
0 Int
0

-- | This function allocates a new block of memory with the given size, pushes
-- onto the stack a new full userdata with the block address, and returns this
-- address. The host program can freely use this memory.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_newuserdata lua_newuserdata>.
newuserdata :: Int -> Lua (Ptr ())
newuserdata :: Int -> Lua (Ptr ())
newuserdata = (State -> CSize -> IO (Ptr ())) -> CSize -> Lua (Ptr ())
forall a b. (State -> a -> IO b) -> a -> Lua b
liftLua1 State -> CSize -> IO (Ptr ())
lua_newuserdata (CSize -> Lua (Ptr ())) -> (Int -> CSize) -> Int -> Lua (Ptr ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | 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'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_next lua_next>.
next :: StackIndex -> Lua Bool
next :: StackIndex -> Lua Bool
next StackIndex
idx = LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> Lua LuaBool -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (State -> Ptr StatusCode -> IO LuaBool) -> Lua LuaBool
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow (\State
l -> State -> StackIndex -> Ptr StatusCode -> IO LuaBool
hslua_next State
l StackIndex
idx)

-- | Opens all standard Lua libraries into the current state and sets each
-- library name as a global value.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#luaL_openlibs luaL_openlibs>.
openlibs :: Lua ()
openlibs :: Lua ()
openlibs = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua State -> IO ()
luaL_openlibs

-- | Pushes Lua's /base/ library onto the stack.
--
-- See <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_base luaopen_base>.
openbase :: Lua ()
openbase :: Lua ()
openbase = CFunction -> Lua ()
pushcfunction CFunction
lua_open_base_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /debug/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_debug luaopen_debug>.
opendebug :: Lua ()
opendebug :: Lua ()
opendebug = CFunction -> Lua ()
pushcfunction CFunction
lua_open_debug_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /io/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_io luaopen_io>.
openio :: Lua ()
openio :: Lua ()
openio = CFunction -> Lua ()
pushcfunction CFunction
lua_open_io_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /math/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_math luaopen_math>.
openmath :: Lua ()
openmath :: Lua ()
openmath = CFunction -> Lua ()
pushcfunction CFunction
lua_open_math_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /os/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_os luaopen_os>.
openos :: Lua ()
openos :: Lua ()
openos = CFunction -> Lua ()
pushcfunction CFunction
lua_open_os_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /package/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_package luaopen_package>.
openpackage :: Lua ()
openpackage :: Lua ()
openpackage = CFunction -> Lua ()
pushcfunction CFunction
lua_open_package_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /string/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_string luaopen_string>.
openstring :: Lua ()
openstring :: Lua ()
openstring = CFunction -> Lua ()
pushcfunction CFunction
lua_open_string_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | Pushes Lua's /table/ library onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#pdf-luaopen_table luaopen_table>.
opentable :: Lua ()
opentable :: Lua ()
opentable = CFunction -> Lua ()
pushcfunction CFunction
lua_open_table_ptr Lua () -> Lua () -> Lua ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> NumArgs -> NumResults -> Lua ()
call NumArgs
0 NumResults
multret

-- | 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.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_pcall lua_pcall>.
pcall :: NumArgs -> NumResults -> Maybe StackIndex -> Lua Status
pcall :: NumArgs -> NumResults -> Maybe StackIndex -> Lua Status
pcall NumArgs
nargs NumResults
nresults Maybe StackIndex
msgh = (State -> IO Status) -> Lua Status
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Status) -> Lua Status)
-> (State -> IO Status) -> Lua Status
forall a b. (a -> b) -> a -> b
$ \State
l ->
  StatusCode -> Status
toStatus (StatusCode -> Status) -> IO StatusCode -> IO Status
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f 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)

-- | Pops @n@ elements from the stack.
--
-- See also: <https://www.lua.org/manual/5.3/manual.html#lua_pop lua_pop>.
pop :: StackIndex -> Lua ()
pop :: StackIndex -> Lua ()
pop StackIndex
n = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> IO ()
lua_pop State
l StackIndex
n

-- | Pushes a boolean value with the given value onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_pushboolean lua_pushboolean>.
pushboolean :: Bool -> Lua ()
pushboolean :: Bool -> Lua ()
pushboolean Bool
b = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> LuaBool -> IO ()
lua_pushboolean State
l (Bool -> LuaBool
toLuaBool Bool
b)

-- | 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 lua_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.
-- lua_pushcclosure also pops these values from the stack.
--
-- The maximum value for @n@ is 255.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_pushcclosure lua_pushcclosure>.
pushcclosure :: CFunction -> NumArgs -> Lua ()
pushcclosure :: CFunction -> NumArgs -> Lua ()
pushcclosure CFunction
f NumArgs
n = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> CFunction -> NumArgs -> IO ()
lua_pushcclosure State
l CFunction
f NumArgs
n

-- | 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'@)
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_pushcfunction lua_pushcfunction>.
pushcfunction :: CFunction -> Lua ()
pushcfunction :: CFunction -> Lua ()
pushcfunction CFunction
f = CFunction -> NumArgs -> Lua ()
pushcclosure CFunction
f NumArgs
0

-- | Pushes the global environment onto the stack.
--
-- Wraps <https://www.lua.org/manual/5.3/manual.html#lua_pushglobaltable \
-- lua_pushglobaltable>.
pushglobaltable :: Lua ()
pushglobaltable :: Lua ()
pushglobaltable = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua State -> IO ()
lua_pushglobaltable

-- | Pushes an integer with with the given value onto the stack.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_pushinteger lua_pushinteger>.
pushinteger :: Lua.Integer -> Lua ()
pushinteger :: Integer -> Lua ()
pushinteger = (State -> Integer -> IO ()) -> Integer -> Lua ()
forall a b. (State -> a -> IO b) -> a -> Lua b
liftLua1 State -> Integer -> IO ()
lua_pushinteger

-- |  Pushes a light userdata onto the stack.
--
-- Userdata represent C values in Lua. A light userdata represents a pointer, a
-- @Ptr ()@ (i.e., @void*@ in C lingo). 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_pushlightuserdata lua_pushlightuserdata>.
pushlightuserdata :: Ptr a -> Lua ()
pushlightuserdata :: Ptr a -> Lua ()
pushlightuserdata = (State -> Ptr a -> IO ()) -> Ptr a -> Lua ()
forall a b. (State -> a -> IO b) -> a -> Lua b
liftLua1 State -> Ptr a -> IO ()
forall a. State -> Ptr a -> IO ()
lua_pushlightuserdata

-- | Pushes a nil value onto the stack.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_pushnil lua_pushnil>.
pushnil :: Lua ()
pushnil :: Lua ()
pushnil = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua State -> IO ()
lua_pushnil

-- | Pushes a float with the given value onto the stack.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_pushnumber lua_pushnumber>.
pushnumber :: Lua.Number -> Lua ()
pushnumber :: Number -> Lua ()
pushnumber = (State -> Number -> IO ()) -> Number -> Lua ()
forall a b. (State -> a -> IO b) -> a -> Lua b
liftLua1 State -> Number -> IO ()
lua_pushnumber

-- | Pushes the zero-terminated 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.
--
-- See also: <https://www.lua.org/manual/5.3/manual.html#lua_pushstring \
-- lua_pushstring>.
pushstring :: ByteString -> Lua ()
pushstring :: ByteString -> Lua ()
pushstring ByteString
s = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
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)

-- | Pushes the current thread onto the stack. Returns @True@ if this thread is
-- the main thread of its state, @False@ otherwise.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_pushthread lua_pushthread>.
pushthread :: Lua Bool
pushthread :: Lua Bool
pushthread = (CInt
1 CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
==)  (CInt -> Bool) -> Lua CInt -> Lua Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (State -> IO CInt) -> Lua CInt
forall a. (State -> IO a) -> Lua a
liftLua State -> IO CInt
lua_pushthread

-- | Pushes a copy of the element at the given index onto the stack.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_pushvalue lua_pushvalue>.
pushvalue :: StackIndex -> Lua ()
pushvalue :: StackIndex -> Lua ()
pushvalue StackIndex
n = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> IO ()
lua_pushvalue State
l StackIndex
n

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_rawequal lua_rawequal>.
rawequal :: StackIndex -> StackIndex -> Lua Bool
rawequal :: StackIndex -> StackIndex -> Lua Bool
rawequal StackIndex
idx1 StackIndex
idx2 = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l ->
  LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> StackIndex -> IO LuaBool
lua_rawequal State
l StackIndex
idx1 StackIndex
idx2

-- | Similar to @'gettable'@, but does a raw access (i.e., without metamethods).
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_rawget lua_rawget>.
rawget :: StackIndex -> Lua ()
rawget :: StackIndex -> Lua ()
rawget StackIndex
n = StackIndex -> (State -> IO ()) -> Lua ()
ensureTable StackIndex
n (\State
l -> State -> StackIndex -> IO ()
lua_rawget State
l StackIndex
n)

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_rawgeti lua_rawgeti>.
rawgeti :: StackIndex -> Lua.Integer -> Lua ()
rawgeti :: StackIndex -> Integer -> Lua ()
rawgeti StackIndex
k Integer
n = StackIndex -> (State -> IO ()) -> Lua ()
ensureTable StackIndex
k (\State
l -> State -> StackIndex -> Integer -> IO ()
lua_rawgeti State
l StackIndex
k Integer
n)

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_rawlen lua_rawlen>.
rawlen :: StackIndex -> Lua Int
rawlen :: StackIndex -> Lua Int
rawlen StackIndex
idx = (State -> IO Int) -> Lua Int
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Int) -> Lua Int) -> (State -> IO Int) -> Lua 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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO CSize
lua_rawlen State
l StackIndex
idx

-- | Similar to @'settable'@, but does a raw assignment (i.e., without
-- metamethods).
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_rawset lua_rawset>.
rawset :: StackIndex -> Lua ()
rawset :: StackIndex -> Lua ()
rawset StackIndex
n = StackIndex -> (State -> IO ()) -> Lua ()
ensureTable StackIndex
n (\State
l -> State -> StackIndex -> IO ()
lua_rawset State
l StackIndex
n)

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_rawseti lua_rawseti>.
rawseti :: StackIndex -> Lua.Integer -> Lua ()
rawseti :: StackIndex -> Integer -> Lua ()
rawseti StackIndex
k Integer
m = StackIndex -> (State -> IO ()) -> Lua ()
ensureTable StackIndex
k (\State
l -> State -> StackIndex -> Integer -> IO ()
lua_rawseti State
l StackIndex
k Integer
m)

-- | Sets the C function @f@ as the new value of global @name@.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_register lua_register>.
register :: String -> CFunction -> Lua ()
register :: String -> CFunction -> Lua ()
register String
name CFunction
f = do
  CFunction -> Lua ()
pushcfunction CFunction
f
  String -> Lua ()
setglobal String
name

-- | 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.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_remove lua_remove>.
remove :: StackIndex -> Lua ()
remove :: StackIndex -> Lua ()
remove StackIndex
n = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> IO ()
lua_remove State
l StackIndex
n

-- | 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.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_replace lua_replace>.
replace :: StackIndex -> Lua ()
replace :: StackIndex -> Lua ()
replace StackIndex
n = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l ->  State -> StackIndex -> IO ()
lua_replace State
l StackIndex
n

-- | 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.3/manual.html#2.4 §2.4> of the Lua 5.3
-- Reference Manual).
--
-- Errors on the Lua side are caught and rethrown as a @'Exception'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_setfield lua_setfield>.
setfield :: StackIndex -> String -> Lua ()
setfield :: StackIndex -> String -> Lua ()
setfield StackIndex
i String
s = do
  StackIndex
absidx <- StackIndex -> Lua StackIndex
absindex StackIndex
i
  ByteString -> Lua ()
pushstring (String -> ByteString
Utf8.fromString String
s)
  StackIndex -> Lua ()
insert (CInt -> StackIndex
nthFromTop CInt
2)
  StackIndex -> Lua ()
settable StackIndex
absidx

-- | 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 a @'Exception'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_setglobal lua_setglobal>.
setglobal :: String -> Lua ()
setglobal :: String -> Lua ()
setglobal String
name = (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow ((State -> Ptr StatusCode -> IO ()) -> Lua ())
-> (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l Ptr StatusCode
status' ->
  String -> (CStringLen -> IO ()) -> IO ()
forall a. String -> (CStringLen -> IO a) -> IO a
C.withCStringLen String
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'

-- | Pops a table from the stack and sets it as the new metatable for the value
-- at the given index.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_setmetatable \
-- lua_setmetatable>.
setmetatable :: StackIndex -> Lua ()
setmetatable :: StackIndex -> Lua ()
setmetatable StackIndex
idx = (State -> IO ()) -> Lua ()
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO ()) -> Lua ()) -> (State -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> IO ()
lua_setmetatable State
l StackIndex
idx

-- | 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.3/manual.html#2.4 §2.4> of the Lua 5.3
-- Reference Manual).
--
-- Errors on the Lua side are caught and rethrown as a @'Exception'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_settable lua_settable>.
settable :: StackIndex -> Lua ()
settable :: StackIndex -> Lua ()
settable StackIndex
index = (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a. (State -> Ptr StatusCode -> IO a) -> Lua a
liftLuaThrow ((State -> Ptr StatusCode -> IO ()) -> Lua ())
-> (State -> Ptr StatusCode -> IO ()) -> Lua ()
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> Ptr StatusCode -> IO ()
hslua_settable State
l StackIndex
index

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_settop lua_settop>.
settop :: StackIndex -> Lua ()
settop :: StackIndex -> Lua ()
settop = (State -> StackIndex -> IO ()) -> StackIndex -> Lua ()
forall a b. (State -> a -> IO b) -> a -> Lua b
liftLua1 State -> StackIndex -> IO ()
lua_settop

-- |  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).
--
-- See also: <https://www.lua.org/manual/5.3/manual.html#lua_status lua_status>.
status :: Lua Status
status :: Lua Status
status = (State -> IO Status) -> Lua Status
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Status) -> Lua Status)
-> (State -> IO Status) -> Lua Status
forall a b. (a -> b) -> a -> b
$ (StatusCode -> Status) -> IO StatusCode -> IO Status
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

-- | 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.)
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_toboolean lua_toboolean>.
toboolean :: StackIndex -> Lua Bool
toboolean :: StackIndex -> Lua Bool
toboolean StackIndex
n = (State -> IO Bool) -> Lua Bool
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO Bool) -> Lua Bool) -> (State -> IO Bool) -> Lua Bool
forall a b. (a -> b) -> a -> b
$ \State
l -> LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> StackIndex -> IO LuaBool
lua_toboolean State
l StackIndex
n

-- | Converts a value at the given index to a C function. That value must be a C
-- function; otherwise, returns @Nothing@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_tocfunction lua_tocfunction>.
tocfunction :: StackIndex -> Lua (Maybe CFunction)
tocfunction :: StackIndex -> Lua (Maybe CFunction)
tocfunction StackIndex
n = (State -> IO (Maybe CFunction)) -> Lua (Maybe CFunction)
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Maybe CFunction)) -> Lua (Maybe CFunction))
-> (State -> IO (Maybe CFunction)) -> Lua (Maybe CFunction)
forall a b. (a -> b) -> a -> b
$ \State
l -> do
  CFunction
fnPtr <- State -> StackIndex -> IO CFunction
lua_tocfunction State
l StackIndex
n
  Maybe CFunction -> IO (Maybe CFunction)
forall (m :: * -> *) a. Monad m => a -> m a
return (if CFunction
fnPtr CFunction -> CFunction -> Bool
forall a. Eq a => a -> a -> Bool
== CFunction
forall a. FunPtr a
nullFunPtr then Maybe CFunction
forall a. Maybe a
Nothing else CFunction -> Maybe CFunction
forall a. a -> Maybe a
Just CFunction
fnPtr)

-- | 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.3/manual.html#3.4.3 §3.4.3> of the Lua 5.3
-- Reference Manual); otherwise, @tointeger@ returns @Nothing@.
--
-- If the number is not an integer, it is truncated in some non-specified way.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_tointeger lua_tointeger>.
tointeger :: StackIndex -> Lua (Maybe Lua.Integer)
tointeger :: StackIndex -> Lua (Maybe Integer)
tointeger StackIndex
n = (State -> IO (Maybe Integer)) -> Lua (Maybe Integer)
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Maybe Integer)) -> Lua (Maybe Integer))
-> (State -> IO (Maybe Integer)) -> Lua (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
  Integer
res <- State -> StackIndex -> Ptr LuaBool -> IO Integer
lua_tointegerx State
l StackIndex
n Ptr LuaBool
boolPtr
  Bool
isNum <- LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr LuaBool -> IO LuaBool
forall a. Storable a => Ptr a -> IO a
F.peek Ptr LuaBool
boolPtr
  Maybe Integer -> IO (Maybe Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (if Bool
isNum then Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
res else Maybe Integer
forall a. Maybe a
Nothing)

-- | Converts the Lua value at the given index to the C type lua_Number. The Lua
-- value must be a number or a string convertible to a number; otherwise,
-- @tonumber@ returns @'Nothing'@.
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_tonumber lua_tonumber>.
tonumber :: StackIndex -> Lua (Maybe Lua.Number)
tonumber :: StackIndex -> Lua (Maybe Number)
tonumber StackIndex
n = (State -> IO (Maybe Number)) -> Lua (Maybe Number)
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Maybe Number)) -> Lua (Maybe Number))
-> (State -> IO (Maybe Number)) -> Lua (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
  Number
res <- State -> StackIndex -> Ptr LuaBool -> IO Number
lua_tonumberx State
l StackIndex
n Ptr LuaBool
bptr
  Bool
isNum <- LuaBool -> Bool
fromLuaBool (LuaBool -> Bool) -> IO LuaBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr LuaBool -> IO LuaBool
forall a. Storable a => Ptr a -> IO a
F.peek Ptr LuaBool
bptr
  Maybe Number -> IO (Maybe Number)
forall (m :: * -> *) a. Monad m => a -> m a
return (if Bool
isNum then Number -> Maybe Number
forall a. a -> Maybe a
Just Number
res else Maybe Number
forall a. Maybe a
Nothing)

-- | 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.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_topointer lua_topointer>.
topointer :: StackIndex -> Lua (Ptr ())
topointer :: StackIndex -> Lua (Ptr ())
topointer StackIndex
n = (State -> IO (Ptr ())) -> Lua (Ptr ())
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Ptr ())) -> Lua (Ptr ()))
-> (State -> IO (Ptr ())) -> Lua (Ptr ())
forall a b. (a -> b) -> a -> b
$ \State
l -> State -> StackIndex -> IO (Ptr ())
lua_topointer State
l StackIndex
n

-- | 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.)
--
-- See <https://www.lua.org/manual/5.3/manual.html#lua_tolstring lua_tolstring>.
tostring :: StackIndex -> Lua (Maybe ByteString)
tostring :: StackIndex -> Lua (Maybe ByteString)
tostring StackIndex
n = (State -> IO (Maybe ByteString)) -> Lua (Maybe ByteString)
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Maybe ByteString)) -> Lua (Maybe ByteString))
-> (State -> IO (Maybe ByteString)) -> Lua (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
    Ptr CChar
cstr <- State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
lua_tolstring State
l StackIndex
n Ptr CSize
lenPtr
    if Ptr CChar
cstr Ptr CChar -> Ptr CChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CChar
forall a. Ptr a
nullPtr
      then Maybe ByteString -> IO (Maybe ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ByteString
forall a. Maybe a
Nothing
      else do
      CSize
cstrLen <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
F.peek Ptr CSize
lenPtr
      ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> IO ByteString -> IO (Maybe ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CStringLen -> IO ByteString
B.packCStringLen (Ptr CChar
cstr, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cstrLen)

-- | 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@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_tothread lua_tothread>.
tothread :: StackIndex -> Lua (Maybe Lua.State)
tothread :: StackIndex -> Lua (Maybe State)
tothread StackIndex
n = (State -> IO (Maybe State)) -> Lua (Maybe State)
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Maybe State)) -> Lua (Maybe State))
-> (State -> IO (Maybe State)) -> Lua (Maybe State)
forall a b. (a -> b) -> a -> b
$ \State
l -> do
  thread :: State
thread@(Lua.State Ptr ()
ptr) <- State -> StackIndex -> IO State
lua_tothread State
l StackIndex
n
  if Ptr ()
ptr Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr ()
forall a. Ptr a
nullPtr
    then Maybe State -> IO (Maybe State)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe State
forall a. Maybe a
Nothing
    else Maybe State -> IO (Maybe State)
forall (m :: * -> *) a. Monad m => a -> m a
return (State -> Maybe State
forall a. a -> Maybe a
Just State
thread)

-- | 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@..
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_touserdata lua_touserdata>.
touserdata :: StackIndex -> Lua (Maybe (Ptr a))
touserdata :: StackIndex -> Lua (Maybe (Ptr a))
touserdata StackIndex
n = (State -> IO (Maybe (Ptr a))) -> Lua (Maybe (Ptr a))
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO (Maybe (Ptr a))) -> Lua (Maybe (Ptr a)))
-> (State -> IO (Maybe (Ptr a))) -> Lua (Maybe (Ptr a))
forall a b. (a -> b) -> a -> b
$ \State
l -> do
  Ptr a
ptr <- State -> StackIndex -> IO (Ptr a)
forall a. State -> StackIndex -> IO (Ptr a)
lua_touserdata State
l StackIndex
n
  if Ptr a
ptr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr
    then Maybe (Ptr a) -> IO (Maybe (Ptr a))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Ptr a)
forall a. Maybe a
Nothing
    else Maybe (Ptr a) -> IO (Maybe (Ptr a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr a -> Maybe (Ptr a)
forall a. a -> Maybe a
Just Ptr a
ptr)

-- | Returns the name of the type encoded by the value @tp@, which must be one
-- the values returned by @'ltype'@.
--
-- See also:
-- <https://www.lua.org/manual/5.3/manual.html#lua_typename lua_typename>.
typename :: Type -> Lua String
typename :: Type -> Lua String
typename Type
tp = (State -> IO String) -> Lua String
forall a. (State -> IO a) -> Lua a
liftLua ((State -> IO String) -> Lua String)
-> (State -> IO String) -> Lua String
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 String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr CChar -> IO String
C.peekCString

-- | Returns the pseudo-index that represents the @i@-th upvalue of the running
-- function (see <https://www.lua.org/manual/5.3/manual.html#4.4 §4.4> of the
-- Lua 5.3 reference manual).
--
-- See also:
-- <https://www.lua.org/manual/5.3/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