hslua-1.0.3: src/Foreign/Lua/Module.hs
{-|
Module : Foreign.Lua.Module
Copyright : © 2019 Albert Krewinkel
License : MIT
Maintainer : Albert Krewinkel <albert+hslua@zeitkraut.de>
Stability : alpha
Portability : Requires GHC 8 or later.
Utility functions for HsLua modules.
-}
module Foreign.Lua.Module
( requirehs
, preloadhs
, addfield
, addfunction
, create
)
where
import Control.Monad (unless)
import Foreign.Lua.Core
import Foreign.Lua.Types (Pushable, push)
import Foreign.Lua.FunctionCalling (ToHaskellFunction, pushHaskellFunction)
-- | Load a module, defined by a Haskell action, under the given name.
--
-- Similar to @luaL_required@: After checking "loaded" table, calls
-- @pushMod@ to push a module to the stack, and registers the result in
-- @package.loaded@ table.
--
-- The @pushMod@ function must push exactly one element to the top of
-- the stack. This is not checked, but failure to do so will lead to
-- problems. Lua's @package@ module must have been loaded by the time
-- this function is invoked.
--
-- Leaves a copy of the module on the stack.
requirehs :: String -> Lua () -> Lua ()
requirehs modname pushMod = do
-- get table of loaded modules
getfield registryindex loadedTableRegistryField
-- Check whether module has already been loaded.
getfield stackTop modname -- LOADED[modname]
alreadyLoaded <- toboolean stackTop
unless alreadyLoaded $ do
pop 1 -- remove field
pushMod -- push module
pushvalue stackTop -- make copy of module
-- add module under the given name (LOADED[modname] = module)
setfield (nthFromTop 3) modname
remove (nthFromTop 2) -- remove table of loaded modules
-- | Registers a preloading function. Takes an module name and the Lua
-- operation which produces the package.
preloadhs :: String -> Lua NumResults -> Lua ()
preloadhs name pushMod = do
getfield registryindex preloadTableRegistryField
pushHaskellFunction pushMod
setfield (nthFromTop 2) name
pop 1
-- | Add a string-indexed field to the table at the top of the stack.
addfield :: Pushable a => String -> a -> Lua ()
addfield name value = do
push name
push value
rawset (nthFromTop 3)
-- | Attach a function to the table at the top of the stack, using the
-- given name.
addfunction :: ToHaskellFunction a => String -> a -> Lua ()
addfunction name fn = do
push name
pushHaskellFunction fn
rawset (nthFromTop 3)
-- | Create a new module (i.e., a Lua table).
create :: Lua ()
create = newtable