lua 1.0.0 → 2.0.0
raw patch · 31 files changed
+2911/−1170 lines, 31 filesdep −bytestringPVP ok
version bump matches the API change (PVP)
Dependencies removed: bytestring
API changes (from Hackage documentation)
- Foreign.Lua.Raw.Auxiliary: RefNil :: Reference
- Foreign.Lua.Raw.Auxiliary: Reference :: CInt -> Reference
- Foreign.Lua.Raw.Auxiliary: data Reference
- Foreign.Lua.Raw.Auxiliary: fromReference :: Reference -> CInt
- Foreign.Lua.Raw.Auxiliary: hsluaL_newstate :: IO State
- Foreign.Lua.Raw.Auxiliary: hsluaL_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
- Foreign.Lua.Raw.Auxiliary: instance GHC.Classes.Eq Foreign.Lua.Raw.Auxiliary.Reference
- Foreign.Lua.Raw.Auxiliary: instance GHC.Show.Show Foreign.Lua.Raw.Auxiliary.Reference
- Foreign.Lua.Raw.Auxiliary: loadedTableRegistryField :: String
- Foreign.Lua.Raw.Auxiliary: luaL_getmetafield :: State -> StackIndex -> CString -> IO TypeCode
- Foreign.Lua.Raw.Auxiliary: luaL_getmetatable :: State -> CString -> IO TypeCode
- Foreign.Lua.Raw.Auxiliary: luaL_loadbuffer :: State -> Ptr CChar -> CSize -> CString -> IO StatusCode
- Foreign.Lua.Raw.Auxiliary: luaL_newmetatable :: State -> CString -> IO LuaBool
- Foreign.Lua.Raw.Auxiliary: luaL_ref :: State -> StackIndex -> IO CInt
- Foreign.Lua.Raw.Auxiliary: luaL_testudata :: State -> StackIndex -> CString -> IO (Ptr ())
- Foreign.Lua.Raw.Auxiliary: luaL_traceback :: State -> State -> CString -> CInt -> IO ()
- Foreign.Lua.Raw.Auxiliary: luaL_unref :: State -> StackIndex -> CInt -> IO ()
- Foreign.Lua.Raw.Auxiliary: preloadTableRegistryField :: String
- Foreign.Lua.Raw.Auxiliary: toReference :: CInt -> Reference
- Foreign.Lua.Raw.Call: hslua_newhsfunction :: State -> StablePtr a -> IO ()
- Foreign.Lua.Raw.Call: hslua_pushhsfunction :: State -> HsFunction -> IO ()
- Foreign.Lua.Raw.Call: type HsFunction = State -> IO NumResults
- Foreign.Lua.Raw.Constants: multret :: NumResults
- Foreign.Lua.Raw.Constants: noref :: Int
- Foreign.Lua.Raw.Constants: refnil :: Int
- Foreign.Lua.Raw.Constants: registryindex :: StackIndex
- Foreign.Lua.Raw.Error: errorMessage :: State -> IO ByteString
- Foreign.Lua.Raw.Functions: hslua_compare :: State -> StackIndex -> StackIndex -> CInt -> Ptr StatusCode -> IO LuaBool
- Foreign.Lua.Raw.Functions: hslua_concat :: State -> NumArgs -> Ptr StatusCode -> IO ()
- Foreign.Lua.Raw.Functions: hslua_error :: State -> IO NumResults
- Foreign.Lua.Raw.Functions: hslua_getglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO ()
- Foreign.Lua.Raw.Functions: hslua_gettable :: State -> StackIndex -> Ptr StatusCode -> IO ()
- Foreign.Lua.Raw.Functions: hslua_next :: State -> StackIndex -> Ptr StatusCode -> IO LuaBool
- Foreign.Lua.Raw.Functions: hslua_setglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO ()
- Foreign.Lua.Raw.Functions: hslua_settable :: State -> StackIndex -> Ptr StatusCode -> IO ()
- Foreign.Lua.Raw.Functions: luaL_openlibs :: State -> IO ()
- Foreign.Lua.Raw.Functions: lua_absindex :: State -> StackIndex -> IO StackIndex
- Foreign.Lua.Raw.Functions: lua_checkstack :: State -> CInt -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_close :: State -> IO ()
- Foreign.Lua.Raw.Functions: lua_copy :: State -> StackIndex -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_createtable :: State -> CInt -> CInt -> IO ()
- Foreign.Lua.Raw.Functions: lua_gc :: State -> CInt -> CInt -> IO CInt
- Foreign.Lua.Raw.Functions: lua_getmetatable :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_gettop :: State -> IO StackIndex
- Foreign.Lua.Raw.Functions: lua_insert :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_iscfunction :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_isinteger :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_isnumber :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_isstring :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_isuserdata :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_load :: State -> Reader -> Ptr () -> CString -> CString -> IO StatusCode
- Foreign.Lua.Raw.Functions: lua_newuserdata :: State -> CSize -> IO (Ptr ())
- Foreign.Lua.Raw.Functions: lua_open_base_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_debug_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_io_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_math_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_os_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_package_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_string_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_open_table_ptr :: CFunction
- Foreign.Lua.Raw.Functions: lua_pcall :: State -> NumArgs -> NumResults -> StackIndex -> IO StatusCode
- Foreign.Lua.Raw.Functions: lua_pop :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushboolean :: State -> LuaBool -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushcclosure :: State -> CFunction -> NumArgs -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushglobaltable :: State -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushinteger :: State -> Integer -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushlightuserdata :: State -> Ptr a -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushlstring :: State -> Ptr CChar -> CSize -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushnil :: State -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushnumber :: State -> Number -> IO ()
- Foreign.Lua.Raw.Functions: lua_pushthread :: State -> IO CInt
- Foreign.Lua.Raw.Functions: lua_pushvalue :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_rawequal :: State -> StackIndex -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_rawget :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_rawgeti :: State -> StackIndex -> Integer -> IO ()
- Foreign.Lua.Raw.Functions: lua_rawlen :: State -> StackIndex -> IO CSize
- Foreign.Lua.Raw.Functions: lua_rawset :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_rawseti :: State -> StackIndex -> Integer -> IO ()
- Foreign.Lua.Raw.Functions: lua_remove :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_replace :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_setmetatable :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_settop :: State -> StackIndex -> IO ()
- Foreign.Lua.Raw.Functions: lua_status :: State -> IO StatusCode
- Foreign.Lua.Raw.Functions: lua_toboolean :: State -> StackIndex -> IO LuaBool
- Foreign.Lua.Raw.Functions: lua_tocfunction :: State -> StackIndex -> IO CFunction
- Foreign.Lua.Raw.Functions: lua_tointegerx :: State -> StackIndex -> Ptr LuaBool -> IO Integer
- Foreign.Lua.Raw.Functions: lua_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
- Foreign.Lua.Raw.Functions: lua_tonumberx :: State -> StackIndex -> Ptr LuaBool -> IO Number
- Foreign.Lua.Raw.Functions: lua_topointer :: State -> StackIndex -> IO (Ptr ())
- Foreign.Lua.Raw.Functions: lua_tothread :: State -> StackIndex -> IO State
- Foreign.Lua.Raw.Functions: lua_touserdata :: State -> StackIndex -> IO (Ptr a)
- Foreign.Lua.Raw.Functions: lua_type :: State -> StackIndex -> IO TypeCode
- Foreign.Lua.Raw.Functions: lua_typename :: State -> TypeCode -> IO CString
- Foreign.Lua.Raw.Types: EQ :: RelationalOperator
- Foreign.Lua.Raw.Types: ErrErr :: Status
- Foreign.Lua.Raw.Types: ErrFile :: Status
- Foreign.Lua.Raw.Types: ErrGcmm :: Status
- Foreign.Lua.Raw.Types: ErrMem :: Status
- Foreign.Lua.Raw.Types: ErrRun :: Status
- Foreign.Lua.Raw.Types: ErrSyntax :: Status
- Foreign.Lua.Raw.Types: GCCOLLECT :: GCCONTROL
- Foreign.Lua.Raw.Types: GCCOUNT :: GCCONTROL
- Foreign.Lua.Raw.Types: GCCOUNTB :: GCCONTROL
- Foreign.Lua.Raw.Types: GCRESTART :: GCCONTROL
- Foreign.Lua.Raw.Types: GCSETPAUSE :: GCCONTROL
- Foreign.Lua.Raw.Types: GCSETSTEPMUL :: GCCONTROL
- Foreign.Lua.Raw.Types: GCSTEP :: GCCONTROL
- Foreign.Lua.Raw.Types: GCSTOP :: GCCONTROL
- Foreign.Lua.Raw.Types: Integer :: Int64 -> Integer
- Foreign.Lua.Raw.Types: LE :: RelationalOperator
- Foreign.Lua.Raw.Types: LT :: RelationalOperator
- Foreign.Lua.Raw.Types: LuaBool :: CInt -> LuaBool
- Foreign.Lua.Raw.Types: NumArgs :: CInt -> NumArgs
- Foreign.Lua.Raw.Types: NumResults :: CInt -> NumResults
- Foreign.Lua.Raw.Types: Number :: Double -> Number
- Foreign.Lua.Raw.Types: OK :: Status
- Foreign.Lua.Raw.Types: StackIndex :: CInt -> StackIndex
- Foreign.Lua.Raw.Types: State :: Ptr () -> State
- Foreign.Lua.Raw.Types: StatusCode :: CInt -> StatusCode
- Foreign.Lua.Raw.Types: TypeBoolean :: Type
- Foreign.Lua.Raw.Types: TypeCode :: CInt -> TypeCode
- Foreign.Lua.Raw.Types: TypeFunction :: Type
- Foreign.Lua.Raw.Types: TypeLightUserdata :: Type
- Foreign.Lua.Raw.Types: TypeNil :: Type
- Foreign.Lua.Raw.Types: TypeNone :: Type
- Foreign.Lua.Raw.Types: TypeNumber :: Type
- Foreign.Lua.Raw.Types: TypeString :: Type
- Foreign.Lua.Raw.Types: TypeTable :: Type
- Foreign.Lua.Raw.Types: TypeThread :: Type
- Foreign.Lua.Raw.Types: TypeUserdata :: Type
- Foreign.Lua.Raw.Types: Yield :: Status
- Foreign.Lua.Raw.Types: [fromNumArgs] :: NumArgs -> CInt
- Foreign.Lua.Raw.Types: [fromNumResults] :: NumResults -> CInt
- Foreign.Lua.Raw.Types: [fromStackIndex] :: StackIndex -> CInt
- Foreign.Lua.Raw.Types: [fromTypeCode] :: TypeCode -> CInt
- Foreign.Lua.Raw.Types: data GCCONTROL
- Foreign.Lua.Raw.Types: data RelationalOperator
- Foreign.Lua.Raw.Types: data Status
- Foreign.Lua.Raw.Types: data Type
- Foreign.Lua.Raw.Types: false :: LuaBool
- Foreign.Lua.Raw.Types: fromLuaBool :: LuaBool -> Bool
- Foreign.Lua.Raw.Types: fromRelationalOperator :: RelationalOperator -> CInt
- Foreign.Lua.Raw.Types: fromType :: Type -> TypeCode
- Foreign.Lua.Raw.Types: instance Foreign.Storable.Storable Foreign.Lua.Raw.Types.LuaBool
- Foreign.Lua.Raw.Types: instance Foreign.Storable.Storable Foreign.Lua.Raw.Types.StatusCode
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.GCCONTROL
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.LuaBool
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.NumArgs
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.NumResults
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.RelationalOperator
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.StackIndex
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.State
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.Status
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.StatusCode
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.Type
- Foreign.Lua.Raw.Types: instance GHC.Classes.Eq Foreign.Lua.Raw.Types.TypeCode
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.GCCONTROL
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.NumArgs
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.NumResults
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.RelationalOperator
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.StackIndex
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.Type
- Foreign.Lua.Raw.Types: instance GHC.Classes.Ord Foreign.Lua.Raw.Types.TypeCode
- Foreign.Lua.Raw.Types: instance GHC.Enum.Bounded Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Enum.Bounded Foreign.Lua.Raw.Types.Type
- Foreign.Lua.Raw.Types: instance GHC.Enum.Enum Foreign.Lua.Raw.Types.GCCONTROL
- Foreign.Lua.Raw.Types: instance GHC.Enum.Enum Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Enum.Enum Foreign.Lua.Raw.Types.StackIndex
- Foreign.Lua.Raw.Types: instance GHC.Enum.Enum Foreign.Lua.Raw.Types.Type
- Foreign.Lua.Raw.Types: instance GHC.Float.Floating Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Float.RealFloat Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Generics.Generic Foreign.Lua.Raw.Types.State
- Foreign.Lua.Raw.Types: instance GHC.Num.Num Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Num.Num Foreign.Lua.Raw.Types.NumArgs
- Foreign.Lua.Raw.Types: instance GHC.Num.Num Foreign.Lua.Raw.Types.NumResults
- Foreign.Lua.Raw.Types: instance GHC.Num.Num Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Num.Num Foreign.Lua.Raw.Types.StackIndex
- Foreign.Lua.Raw.Types: instance GHC.Real.Fractional Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Real.Integral Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Real.Real Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Real.Real Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Real.RealFrac Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.GCCONTROL
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.Integer
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.LuaBool
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.NumArgs
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.NumResults
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.Number
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.RelationalOperator
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.StackIndex
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.Status
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.Type
- Foreign.Lua.Raw.Types: instance GHC.Show.Show Foreign.Lua.Raw.Types.TypeCode
- Foreign.Lua.Raw.Types: newtype Integer
- Foreign.Lua.Raw.Types: newtype LuaBool
- Foreign.Lua.Raw.Types: newtype NumArgs
- Foreign.Lua.Raw.Types: newtype NumResults
- Foreign.Lua.Raw.Types: newtype Number
- Foreign.Lua.Raw.Types: newtype StackIndex
- Foreign.Lua.Raw.Types: newtype State
- Foreign.Lua.Raw.Types: newtype StatusCode
- Foreign.Lua.Raw.Types: newtype TypeCode
- Foreign.Lua.Raw.Types: toLuaBool :: Bool -> LuaBool
- Foreign.Lua.Raw.Types: toStatus :: StatusCode -> Status
- Foreign.Lua.Raw.Types: toType :: TypeCode -> Type
- Foreign.Lua.Raw.Types: true :: LuaBool
- Foreign.Lua.Raw.Types: type CFunction = FunPtr (State -> IO NumResults)
- Foreign.Lua.Raw.Types: type Reader = FunPtr (State -> Ptr () -> Ptr CSize -> IO (Ptr CChar))
- Foreign.Lua.Raw.Userdata: hslua_fromuserdata :: State -> StackIndex -> CString -> IO (Maybe a)
- Foreign.Lua.Raw.Userdata: hslua_newhsuserdata :: State -> a -> IO ()
- Foreign.Lua.Raw.Userdata: hslua_newudmetatable :: State -> CString -> IO LuaBool
+ Lua: GCCode :: CInt -> GCCode
+ Lua: Integer :: Int64 -> Integer
+ Lua: LuaBool :: CInt -> LuaBool
+ Lua: NumArgs :: CInt -> NumArgs
+ Lua: NumResults :: CInt -> NumResults
+ Lua: Number :: Double -> Number
+ Lua: OPCode :: CInt -> OPCode
+ Lua: RefNil :: Reference
+ Lua: Reference :: CInt -> Reference
+ Lua: StackIndex :: CInt -> StackIndex
+ Lua: State :: Ptr () -> State
+ Lua: StatusCode :: CInt -> StatusCode
+ Lua: TypeCode :: CInt -> TypeCode
+ Lua: [fromNumArgs] :: NumArgs -> CInt
+ Lua: [fromNumResults] :: NumResults -> CInt
+ Lua: [fromStackIndex] :: StackIndex -> CInt
+ Lua: [fromTypeCode] :: TypeCode -> CInt
+ Lua: data Reference
+ Lua: fromReference :: Reference -> CInt
+ Lua: hsluaL_newstate :: IO State
+ Lua: hsluaL_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
+ Lua: hslua_compare :: State -> StackIndex -> StackIndex -> OPCode -> Ptr StatusCode -> IO LuaBool
+ Lua: hslua_concat :: State -> NumArgs -> Ptr StatusCode -> IO ()
+ Lua: hslua_error :: State -> IO NumResults
+ Lua: hslua_getglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO TypeCode
+ Lua: hslua_gettable :: State -> StackIndex -> Ptr StatusCode -> IO TypeCode
+ Lua: hslua_next :: State -> StackIndex -> Ptr StatusCode -> IO LuaBool
+ Lua: hslua_pushhsfunction :: State -> PreCFunction -> IO ()
+ Lua: hslua_setglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO ()
+ Lua: hslua_settable :: State -> StackIndex -> Ptr StatusCode -> IO ()
+ Lua: loadedTableRegistryField :: String
+ Lua: luaL_getmetafield :: State -> StackIndex -> CString -> IO TypeCode
+ Lua: luaL_getmetatable :: State -> CString -> IO TypeCode
+ Lua: luaL_loadbuffer :: State -> Ptr CChar -> CSize -> CString -> IO StatusCode
+ Lua: luaL_newmetatable :: State -> CString -> IO LuaBool
+ Lua: luaL_openlibs :: State -> IO ()
+ Lua: luaL_ref :: State -> StackIndex -> IO CInt
+ Lua: luaL_testudata :: State -> StackIndex -> CString -> IO (Ptr ())
+ Lua: luaL_traceback :: State -> State -> CString -> CInt -> IO ()
+ Lua: luaL_unref :: State -> StackIndex -> CInt -> IO ()
+ Lua: lua_absindex :: State -> StackIndex -> IO StackIndex
+ Lua: lua_checkstack :: State -> CInt -> IO LuaBool
+ Lua: lua_close :: State -> IO ()
+ Lua: lua_concat :: State -> CInt -> IO ()
+ Lua: lua_copy :: State -> StackIndex -> StackIndex -> IO ()
+ Lua: lua_createtable :: State -> CInt -> CInt -> IO ()
+ Lua: lua_gc :: State -> GCCode -> CInt -> IO CInt
+ Lua: lua_getglobal :: State -> CString -> IO TypeCode
+ Lua: lua_getmetatable :: State -> StackIndex -> IO LuaBool
+ Lua: lua_gettable :: State -> StackIndex -> IO TypeCode
+ Lua: lua_gettop :: State -> IO StackIndex
+ Lua: lua_getuservalue :: State -> StackIndex -> IO TypeCode
+ Lua: lua_insert :: State -> StackIndex -> IO ()
+ Lua: lua_isboolean :: State -> StackIndex -> IO LuaBool
+ Lua: lua_iscfunction :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isfunction :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isinteger :: State -> StackIndex -> IO LuaBool
+ Lua: lua_islightuserdata :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isnil :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isnone :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isnoneornil :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isnumber :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isstring :: State -> StackIndex -> IO LuaBool
+ Lua: lua_istable :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isthread :: State -> StackIndex -> IO LuaBool
+ Lua: lua_isuserdata :: State -> StackIndex -> IO LuaBool
+ Lua: lua_load :: State -> Reader -> Ptr () -> CString -> CString -> IO StatusCode
+ Lua: lua_newthread :: State -> IO State
+ Lua: lua_newuserdata :: State -> CSize -> IO (Ptr ())
+ Lua: lua_next :: State -> StackIndex -> IO LuaBool
+ Lua: lua_pcall :: State -> NumArgs -> NumResults -> StackIndex -> IO StatusCode
+ Lua: lua_pop :: State -> CInt -> IO ()
+ Lua: lua_pushboolean :: State -> LuaBool -> IO ()
+ Lua: lua_pushcclosure :: State -> CFunction -> NumArgs -> IO ()
+ Lua: lua_pushglobaltable :: State -> IO ()
+ Lua: lua_pushinteger :: State -> Integer -> IO ()
+ Lua: lua_pushlightuserdata :: State -> Ptr a -> IO ()
+ Lua: lua_pushlstring :: State -> Ptr CChar -> CSize -> IO ()
+ Lua: lua_pushnil :: State -> IO ()
+ Lua: lua_pushnumber :: State -> Number -> IO ()
+ Lua: lua_pushstring :: State -> CString -> IO CString
+ Lua: lua_pushthread :: State -> IO CInt
+ Lua: lua_pushvalue :: State -> StackIndex -> IO ()
+ Lua: lua_rawequal :: State -> StackIndex -> StackIndex -> IO LuaBool
+ Lua: lua_rawget :: State -> StackIndex -> IO ()
+ Lua: lua_rawgeti :: State -> StackIndex -> Integer -> IO ()
+ Lua: lua_rawlen :: State -> StackIndex -> IO CSize
+ Lua: lua_rawset :: State -> StackIndex -> IO ()
+ Lua: lua_rawseti :: State -> StackIndex -> Integer -> IO ()
+ Lua: lua_remove :: State -> StackIndex -> IO ()
+ Lua: lua_replace :: State -> StackIndex -> IO ()
+ Lua: lua_setglobal :: State -> CString -> IO ()
+ Lua: lua_setmetatable :: State -> StackIndex -> IO ()
+ Lua: lua_settable :: State -> StackIndex -> IO ()
+ Lua: lua_settop :: State -> StackIndex -> IO ()
+ Lua: lua_setuservalue :: State -> StackIndex -> IO ()
+ Lua: lua_status :: State -> IO StatusCode
+ Lua: lua_toboolean :: State -> StackIndex -> IO LuaBool
+ Lua: lua_tocfunction :: State -> StackIndex -> IO CFunction
+ Lua: lua_tointegerx :: State -> StackIndex -> Ptr LuaBool -> IO Integer
+ Lua: lua_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
+ Lua: lua_tonumberx :: State -> StackIndex -> Ptr LuaBool -> IO Number
+ Lua: lua_topointer :: State -> StackIndex -> IO (Ptr ())
+ Lua: lua_tothread :: State -> StackIndex -> IO State
+ Lua: lua_touserdata :: State -> StackIndex -> IO (Ptr a)
+ Lua: lua_type :: State -> StackIndex -> IO TypeCode
+ Lua: lua_typename :: State -> TypeCode -> IO CString
+ Lua: luaopen_base :: CFunction
+ Lua: luaopen_debug :: CFunction
+ Lua: luaopen_io :: CFunction
+ Lua: luaopen_math :: CFunction
+ Lua: luaopen_os :: CFunction
+ Lua: luaopen_package :: CFunction
+ Lua: luaopen_string :: CFunction
+ Lua: luaopen_table :: CFunction
+ Lua: newtype GCCode
+ Lua: newtype Integer
+ Lua: newtype LuaBool
+ Lua: newtype NumArgs
+ Lua: newtype NumResults
+ Lua: newtype Number
+ Lua: newtype OPCode
+ Lua: newtype StackIndex
+ Lua: newtype State
+ Lua: newtype StatusCode
+ Lua: newtype TypeCode
+ Lua: nth :: CInt -> StackIndex
+ Lua: nthBottom :: CInt -> StackIndex
+ Lua: nthTop :: CInt -> StackIndex
+ Lua: pattern FALSE :: LuaBool
+ Lua: pattern LUA_ERRERR :: StatusCode
+ Lua: pattern LUA_ERRFILE :: StatusCode
+ Lua: pattern LUA_ERRGCMM :: StatusCode
+ Lua: pattern LUA_ERRMEM :: StatusCode
+ Lua: pattern LUA_ERRRUN :: StatusCode
+ Lua: pattern LUA_ERRSYNTAX :: StatusCode
+ Lua: pattern LUA_GCCOLLECT :: GCCode
+ Lua: pattern LUA_GCCOUNT :: GCCode
+ Lua: pattern LUA_GCCOUNTB :: GCCode
+ Lua: pattern LUA_GCISRUNNING :: GCCode
+ Lua: pattern LUA_GCRESTART :: GCCode
+ Lua: pattern LUA_GCSETPAUSE :: GCCode
+ Lua: pattern LUA_GCSETSTEPMUL :: GCCode
+ Lua: pattern LUA_GCSTEP :: GCCode
+ Lua: pattern LUA_GCSTOP :: GCCode
+ Lua: pattern LUA_MULTRET :: NumResults
+ Lua: pattern LUA_NOREF :: CInt
+ Lua: pattern LUA_OK :: StatusCode
+ Lua: pattern LUA_OPEQ :: OPCode
+ Lua: pattern LUA_OPLE :: OPCode
+ Lua: pattern LUA_OPLT :: OPCode
+ Lua: pattern LUA_REFNIL :: CInt
+ Lua: pattern LUA_REGISTRYINDEX :: StackIndex
+ Lua: pattern LUA_TBOOLEAN :: TypeCode
+ Lua: pattern LUA_TFUNCTION :: TypeCode
+ Lua: pattern LUA_TLIGHTUSERDATA :: TypeCode
+ Lua: pattern LUA_TNIL :: TypeCode
+ Lua: pattern LUA_TNONE :: TypeCode
+ Lua: pattern LUA_TNUMBER :: TypeCode
+ Lua: pattern LUA_TSTRING :: TypeCode
+ Lua: pattern LUA_TTABLE :: TypeCode
+ Lua: pattern LUA_TTHREAD :: TypeCode
+ Lua: pattern LUA_TUSERDATA :: TypeCode
+ Lua: pattern LUA_YIELD :: StatusCode
+ Lua: pattern TRUE :: LuaBool
+ Lua: preloadTableRegistryField :: String
+ Lua: toReference :: CInt -> Reference
+ Lua: top :: StackIndex
+ Lua: type CFunction = FunPtr PreCFunction
+ Lua: type PreCFunction = State -> IO NumResults
+ Lua: type Reader = FunPtr (State -> Ptr () -> Ptr CSize -> IO (Ptr CChar))
+ Lua: withNewState :: (State -> IO a) -> IO a
+ Lua.Auxiliary: RefNil :: Reference
+ Lua.Auxiliary: Reference :: CInt -> Reference
+ Lua.Auxiliary: data Reference
+ Lua.Auxiliary: fromReference :: Reference -> CInt
+ Lua.Auxiliary: instance GHC.Classes.Eq Lua.Auxiliary.Reference
+ Lua.Auxiliary: instance GHC.Show.Show Lua.Auxiliary.Reference
+ Lua.Auxiliary: loadedTableRegistryField :: String
+ Lua.Auxiliary: luaL_getmetafield :: State -> StackIndex -> CString -> IO TypeCode
+ Lua.Auxiliary: luaL_getmetatable :: State -> CString -> IO TypeCode
+ Lua.Auxiliary: luaL_loadbuffer :: State -> Ptr CChar -> CSize -> CString -> IO StatusCode
+ Lua.Auxiliary: luaL_loadfile :: State -> Ptr CChar -> IO StatusCode
+ Lua.Auxiliary: luaL_loadfilex :: State -> Ptr CChar -> Ptr CChar -> IO StatusCode
+ Lua.Auxiliary: luaL_newmetatable :: State -> CString -> IO LuaBool
+ Lua.Auxiliary: luaL_openlibs :: State -> IO ()
+ Lua.Auxiliary: luaL_ref :: State -> StackIndex -> IO CInt
+ Lua.Auxiliary: luaL_testudata :: State -> StackIndex -> CString -> IO (Ptr ())
+ Lua.Auxiliary: luaL_traceback :: State -> State -> CString -> CInt -> IO ()
+ Lua.Auxiliary: luaL_unref :: State -> StackIndex -> CInt -> IO ()
+ Lua.Auxiliary: luaL_where :: State -> CInt -> IO ()
+ Lua.Auxiliary: preloadTableRegistryField :: String
+ Lua.Auxiliary: toReference :: CInt -> Reference
+ Lua.Call: hslua_pushhsfunction :: State -> PreCFunction -> IO ()
+ Lua.Constants: pattern FALSE :: LuaBool
+ Lua.Constants: pattern LUA_ERRERR :: StatusCode
+ Lua.Constants: pattern LUA_ERRFILE :: StatusCode
+ Lua.Constants: pattern LUA_ERRGCMM :: StatusCode
+ Lua.Constants: pattern LUA_ERRMEM :: StatusCode
+ Lua.Constants: pattern LUA_ERRRUN :: StatusCode
+ Lua.Constants: pattern LUA_ERRSYNTAX :: StatusCode
+ Lua.Constants: pattern LUA_GCCOLLECT :: GCCode
+ Lua.Constants: pattern LUA_GCCOUNT :: GCCode
+ Lua.Constants: pattern LUA_GCCOUNTB :: GCCode
+ Lua.Constants: pattern LUA_GCISRUNNING :: GCCode
+ Lua.Constants: pattern LUA_GCRESTART :: GCCode
+ Lua.Constants: pattern LUA_GCSETPAUSE :: GCCode
+ Lua.Constants: pattern LUA_GCSETSTEPMUL :: GCCode
+ Lua.Constants: pattern LUA_GCSTEP :: GCCode
+ Lua.Constants: pattern LUA_GCSTOP :: GCCode
+ Lua.Constants: pattern LUA_MULTRET :: NumResults
+ Lua.Constants: pattern LUA_NOREF :: CInt
+ Lua.Constants: pattern LUA_OK :: StatusCode
+ Lua.Constants: pattern LUA_OPEQ :: OPCode
+ Lua.Constants: pattern LUA_OPLE :: OPCode
+ Lua.Constants: pattern LUA_OPLT :: OPCode
+ Lua.Constants: pattern LUA_REFNIL :: CInt
+ Lua.Constants: pattern LUA_REGISTRYINDEX :: StackIndex
+ Lua.Constants: pattern LUA_TBOOLEAN :: TypeCode
+ Lua.Constants: pattern LUA_TFUNCTION :: TypeCode
+ Lua.Constants: pattern LUA_TLIGHTUSERDATA :: TypeCode
+ Lua.Constants: pattern LUA_TNIL :: TypeCode
+ Lua.Constants: pattern LUA_TNONE :: TypeCode
+ Lua.Constants: pattern LUA_TNUMBER :: TypeCode
+ Lua.Constants: pattern LUA_TSTRING :: TypeCode
+ Lua.Constants: pattern LUA_TTABLE :: TypeCode
+ Lua.Constants: pattern LUA_TTHREAD :: TypeCode
+ Lua.Constants: pattern LUA_TUSERDATA :: TypeCode
+ Lua.Constants: pattern LUA_YIELD :: StatusCode
+ Lua.Constants: pattern TRUE :: LuaBool
+ Lua.Ersatz: hsluaL_newstate :: IO State
+ Lua.Ersatz: hsluaL_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
+ Lua.Ersatz: hslua_compare :: State -> StackIndex -> StackIndex -> OPCode -> Ptr StatusCode -> IO LuaBool
+ Lua.Ersatz: hslua_concat :: State -> NumArgs -> Ptr StatusCode -> IO ()
+ Lua.Ersatz: hslua_error :: State -> IO NumResults
+ Lua.Ersatz: hslua_getglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO TypeCode
+ Lua.Ersatz: hslua_gettable :: State -> StackIndex -> Ptr StatusCode -> IO TypeCode
+ Lua.Ersatz: hslua_next :: State -> StackIndex -> Ptr StatusCode -> IO LuaBool
+ Lua.Ersatz: hslua_setglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO ()
+ Lua.Ersatz: hslua_settable :: State -> StackIndex -> Ptr StatusCode -> IO ()
+ Lua.Ersatz.Auxiliary: hsluaL_newstate :: IO State
+ Lua.Ersatz.Auxiliary: hsluaL_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
+ Lua.Ersatz.Functions: hslua_compare :: State -> StackIndex -> StackIndex -> OPCode -> Ptr StatusCode -> IO LuaBool
+ Lua.Ersatz.Functions: hslua_concat :: State -> NumArgs -> Ptr StatusCode -> IO ()
+ Lua.Ersatz.Functions: hslua_error :: State -> IO NumResults
+ Lua.Ersatz.Functions: hslua_getglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO TypeCode
+ Lua.Ersatz.Functions: hslua_gettable :: State -> StackIndex -> Ptr StatusCode -> IO TypeCode
+ Lua.Ersatz.Functions: hslua_next :: State -> StackIndex -> Ptr StatusCode -> IO LuaBool
+ Lua.Ersatz.Functions: hslua_setglobal :: State -> CString -> CSize -> Ptr StatusCode -> IO ()
+ Lua.Ersatz.Functions: hslua_settable :: State -> StackIndex -> Ptr StatusCode -> IO ()
+ Lua.Lib: luaopen_base :: CFunction
+ Lua.Lib: luaopen_debug :: CFunction
+ Lua.Lib: luaopen_io :: CFunction
+ Lua.Lib: luaopen_math :: CFunction
+ Lua.Lib: luaopen_os :: CFunction
+ Lua.Lib: luaopen_package :: CFunction
+ Lua.Lib: luaopen_string :: CFunction
+ Lua.Lib: luaopen_table :: CFunction
+ Lua.Primary: lua_absindex :: State -> StackIndex -> IO StackIndex
+ Lua.Primary: lua_checkstack :: State -> CInt -> IO LuaBool
+ Lua.Primary: lua_close :: State -> IO ()
+ Lua.Primary: lua_concat :: State -> CInt -> IO ()
+ Lua.Primary: lua_copy :: State -> StackIndex -> StackIndex -> IO ()
+ Lua.Primary: lua_createtable :: State -> CInt -> CInt -> IO ()
+ Lua.Primary: lua_gc :: State -> GCCode -> CInt -> IO CInt
+ Lua.Primary: lua_getglobal :: State -> CString -> IO TypeCode
+ Lua.Primary: lua_getmetatable :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_gettable :: State -> StackIndex -> IO TypeCode
+ Lua.Primary: lua_gettop :: State -> IO StackIndex
+ Lua.Primary: lua_getuservalue :: State -> StackIndex -> IO TypeCode
+ Lua.Primary: lua_insert :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_isboolean :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_iscfunction :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isfunction :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isinteger :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_islightuserdata :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isnil :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isnone :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isnoneornil :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isnumber :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isstring :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_istable :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isthread :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_isuserdata :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_load :: State -> Reader -> Ptr () -> CString -> CString -> IO StatusCode
+ Lua.Primary: lua_newthread :: State -> IO State
+ Lua.Primary: lua_newuserdata :: State -> CSize -> IO (Ptr ())
+ Lua.Primary: lua_next :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_pcall :: State -> NumArgs -> NumResults -> StackIndex -> IO StatusCode
+ Lua.Primary: lua_pop :: State -> CInt -> IO ()
+ Lua.Primary: lua_pushboolean :: State -> LuaBool -> IO ()
+ Lua.Primary: lua_pushcclosure :: State -> CFunction -> NumArgs -> IO ()
+ Lua.Primary: lua_pushglobaltable :: State -> IO ()
+ Lua.Primary: lua_pushinteger :: State -> Integer -> IO ()
+ Lua.Primary: lua_pushlightuserdata :: State -> Ptr a -> IO ()
+ Lua.Primary: lua_pushlstring :: State -> Ptr CChar -> CSize -> IO ()
+ Lua.Primary: lua_pushnil :: State -> IO ()
+ Lua.Primary: lua_pushnumber :: State -> Number -> IO ()
+ Lua.Primary: lua_pushstring :: State -> CString -> IO CString
+ Lua.Primary: lua_pushthread :: State -> IO CInt
+ Lua.Primary: lua_pushvalue :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_rawequal :: State -> StackIndex -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_rawget :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_rawgeti :: State -> StackIndex -> Integer -> IO ()
+ Lua.Primary: lua_rawlen :: State -> StackIndex -> IO CSize
+ Lua.Primary: lua_rawset :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_rawseti :: State -> StackIndex -> Integer -> IO ()
+ Lua.Primary: lua_remove :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_replace :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_setglobal :: State -> CString -> IO ()
+ Lua.Primary: lua_setmetatable :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_settable :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_settop :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_setuservalue :: State -> StackIndex -> IO ()
+ Lua.Primary: lua_status :: State -> IO StatusCode
+ Lua.Primary: lua_toboolean :: State -> StackIndex -> IO LuaBool
+ Lua.Primary: lua_tocfunction :: State -> StackIndex -> IO CFunction
+ Lua.Primary: lua_tointegerx :: State -> StackIndex -> Ptr LuaBool -> IO Integer
+ Lua.Primary: lua_tolstring :: State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
+ Lua.Primary: lua_tonumberx :: State -> StackIndex -> Ptr LuaBool -> IO Number
+ Lua.Primary: lua_topointer :: State -> StackIndex -> IO (Ptr ())
+ Lua.Primary: lua_tothread :: State -> StackIndex -> IO State
+ Lua.Primary: lua_touserdata :: State -> StackIndex -> IO (Ptr a)
+ Lua.Primary: lua_type :: State -> StackIndex -> IO TypeCode
+ Lua.Primary: lua_typename :: State -> TypeCode -> IO CString
+ Lua.Types: GCCode :: CInt -> GCCode
+ Lua.Types: Integer :: Int64 -> Integer
+ Lua.Types: LuaBool :: CInt -> LuaBool
+ Lua.Types: NumArgs :: CInt -> NumArgs
+ Lua.Types: NumResults :: CInt -> NumResults
+ Lua.Types: Number :: Double -> Number
+ Lua.Types: OPCode :: CInt -> OPCode
+ Lua.Types: StackIndex :: CInt -> StackIndex
+ Lua.Types: State :: Ptr () -> State
+ Lua.Types: StatusCode :: CInt -> StatusCode
+ Lua.Types: TypeCode :: CInt -> TypeCode
+ Lua.Types: [fromNumArgs] :: NumArgs -> CInt
+ Lua.Types: [fromNumResults] :: NumResults -> CInt
+ Lua.Types: [fromStackIndex] :: StackIndex -> CInt
+ Lua.Types: [fromTypeCode] :: TypeCode -> CInt
+ Lua.Types: instance Foreign.Storable.Storable Lua.Types.GCCode
+ Lua.Types: instance Foreign.Storable.Storable Lua.Types.LuaBool
+ Lua.Types: instance Foreign.Storable.Storable Lua.Types.OPCode
+ Lua.Types: instance Foreign.Storable.Storable Lua.Types.StatusCode
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.GCCode
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.Integer
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.LuaBool
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.NumArgs
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.NumResults
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.Number
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.OPCode
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.StackIndex
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.State
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.StatusCode
+ Lua.Types: instance GHC.Classes.Eq Lua.Types.TypeCode
+ Lua.Types: instance GHC.Classes.Ord Lua.Types.Integer
+ Lua.Types: instance GHC.Classes.Ord Lua.Types.NumArgs
+ Lua.Types: instance GHC.Classes.Ord Lua.Types.NumResults
+ Lua.Types: instance GHC.Classes.Ord Lua.Types.Number
+ Lua.Types: instance GHC.Classes.Ord Lua.Types.StackIndex
+ Lua.Types: instance GHC.Classes.Ord Lua.Types.TypeCode
+ Lua.Types: instance GHC.Enum.Bounded Lua.Types.Integer
+ Lua.Types: instance GHC.Enum.Enum Lua.Types.Integer
+ Lua.Types: instance GHC.Enum.Enum Lua.Types.StackIndex
+ Lua.Types: instance GHC.Float.Floating Lua.Types.Number
+ Lua.Types: instance GHC.Float.RealFloat Lua.Types.Number
+ Lua.Types: instance GHC.Generics.Generic Lua.Types.State
+ Lua.Types: instance GHC.Num.Num Lua.Types.Integer
+ Lua.Types: instance GHC.Num.Num Lua.Types.NumArgs
+ Lua.Types: instance GHC.Num.Num Lua.Types.NumResults
+ Lua.Types: instance GHC.Num.Num Lua.Types.Number
+ Lua.Types: instance GHC.Num.Num Lua.Types.StackIndex
+ Lua.Types: instance GHC.Real.Fractional Lua.Types.Number
+ Lua.Types: instance GHC.Real.Integral Lua.Types.Integer
+ Lua.Types: instance GHC.Real.Real Lua.Types.Integer
+ Lua.Types: instance GHC.Real.Real Lua.Types.Number
+ Lua.Types: instance GHC.Real.RealFrac Lua.Types.Number
+ Lua.Types: instance GHC.Show.Show Lua.Types.Integer
+ Lua.Types: instance GHC.Show.Show Lua.Types.LuaBool
+ Lua.Types: instance GHC.Show.Show Lua.Types.NumArgs
+ Lua.Types: instance GHC.Show.Show Lua.Types.NumResults
+ Lua.Types: instance GHC.Show.Show Lua.Types.Number
+ Lua.Types: instance GHC.Show.Show Lua.Types.StackIndex
+ Lua.Types: instance GHC.Show.Show Lua.Types.TypeCode
+ Lua.Types: newtype GCCode
+ Lua.Types: newtype Integer
+ Lua.Types: newtype LuaBool
+ Lua.Types: newtype NumArgs
+ Lua.Types: newtype NumResults
+ Lua.Types: newtype Number
+ Lua.Types: newtype OPCode
+ Lua.Types: newtype StackIndex
+ Lua.Types: newtype State
+ Lua.Types: newtype StatusCode
+ Lua.Types: newtype TypeCode
+ Lua.Types: type CFunction = FunPtr PreCFunction
+ Lua.Types: type PreCFunction = State -> IO NumResults
+ Lua.Types: type Reader = FunPtr (State -> Ptr () -> Ptr CSize -> IO (Ptr CChar))
+ Lua.Userdata: hslua_fromuserdata :: State -> StackIndex -> CString -> IO (Maybe a)
+ Lua.Userdata: hslua_newhsuserdata :: State -> a -> IO ()
+ Lua.Userdata: hslua_newudmetatable :: State -> CString -> IO LuaBool
+ Lua.Userdata: hslua_putuserdata :: State -> StackIndex -> CString -> a -> IO Bool
Files
- CHANGELOG.md +42/−2
- cbits/hslua/hslauxlib.c +52/−0
- cbits/hslua/hslauxlib.h +21/−0
- cbits/hslua/hslcall.c +7/−6
- cbits/hslua/hslexport.h +9/−0
- cbits/hslua/hslua-export.h +0/−8
- cbits/hslua/hslua.c +14/−49
- cbits/hslua/hslua.h +3/−15
- cbits/hslua/hsludata.c +4/−1
- cbits/hslua/hsludata.h +1/−0
- lua.cabal +37/−24
- src/Foreign/Lua/Raw/Auxiliary.hs +0/−133
- src/Foreign/Lua/Raw/Call.hs +0/−65
- src/Foreign/Lua/Raw/Constants.hs +0/−39
- src/Foreign/Lua/Raw/Error.hs +0/−40
- src/Foreign/Lua/Raw/Functions.hs +0/−403
- src/Foreign/Lua/Raw/Types.hsc +0/−281
- src/Foreign/Lua/Raw/Userdata.hs +0/−65
- src/Lua.hs +293/−0
- src/Lua/Auxiliary.hs +234/−0
- src/Lua/Call.hs +90/−0
- src/Lua/Constants.hsc +243/−0
- src/Lua/Ersatz.hs +31/−0
- src/Lua/Ersatz/Auxiliary.hs +32/−0
- src/Lua/Ersatz/Functions.hs +122/−0
- src/Lua/Lib.hs +59/−0
- src/Lua/Primary.hs +896/−0
- src/Lua/Types.hsc +143/−0
- src/Lua/Userdata.hs +85/−0
- test/Lua/UnsafeTests.hs +131/−0
- test/test-lua.hs +362/−39
CHANGELOG.md view
@@ -2,9 +2,49 @@ `lua` uses [PVP Versioning][1]. -## lua 1.0+## lua 2.0.0 -Release pending+Release pending.++- Module hierarchy moved from `Foreign.Lua.Raw` to `Lua`.++- Documentation has been improved.++- Added new function `withNewState` to run Lua operations.++- New modules `Lua.Ersatz` containing all bindings to safe+ ersatz functions.++- Higher level and enum types have been removed, only the+ low-level "code" types are kept in this package.++- Constants are now represented as pattern synonyms like `LUA_OK`.++- Provide bindings to more functions:+ + `lua_is...` type-checking functions;+ + `lua_pushstring` to push plain CStrings;+ + auxiliary functions+ * `luaL_loadfile`, and+ * `luaL_loadfilex`;+ + unsafe functions+ * `lua_gettable`,+ * `lua_settable`,+ * `lua_getglobal`, and+ * `lua_setglobal`.++- The function `lua_pop` now expects a `CInt` instead of a+ `StackIndex`.++- New StackIndex constructor functions `nthTop`, `nthBottom`,+ `nth`, and `top`.++- Avoid unnecessary modification of HSFUN metatable.++- Various cleanups and test improvements.++## lua 1.0.0++Released 2021-02-18. - Initially created. Contains all modules in the `Foreign.Lua.Raw` hierarchy from `hslua-1.3`. Documentation has been improved.
+ cbits/hslua/hslauxlib.c view
@@ -0,0 +1,52 @@+#include <HsFFI.h>+#include <lua.h>+#include <lauxlib.h>+#include "hslauxlib.h"+#include "hslcall.h"++/* Auxiliary Library */++/*+** Creates a new Lua state and set extra registry values for error+** bookkeeping.+*/+lua_State *hsluaL_newstate()+{+ lua_State *L = luaL_newstate();++ /* add error value */+ lua_createtable(L, 0, 0);+ lua_setfield(L, LUA_REGISTRYINDEX, HSLUA_ERR);++ /* register HaskellFunction userdata metatable */+ hslua_registerhsfunmetatable(L);++ return L;+}+++/*+** Helper for hsluaL_tostring+*/+int hsluaL__tolstring(lua_State *L)+{+ luaL_tolstring(L, 1, NULL);+ return 1;+}++/*+** Converts object to string, respecting any metamethods; returns NULL+** if an error occurs.+*/+const char *hsluaL_tolstring(lua_State *L, int index, size_t *len)+{+ lua_pushvalue(L, index);+ lua_pushcfunction(L, hsluaL__tolstring);+ lua_insert(L, -2);+ int res = lua_pcall(L, 1, 1, 0);+ if (res != LUA_OK) {+ /* error */+ return NULL;+ }+ return lua_tolstring(L, -1, len);+}
+ cbits/hslua/hslauxlib.h view
@@ -0,0 +1,21 @@+#ifndef hslauxlib_h+#define hslauxlib_h++#include <HsFFI.h>+#include <lua.h>+#include <lauxlib.h>++/* Auxiliary Library */++/*+** Creates a new state for use with the Haskell bindings.+*/+lua_State *hsluaL_newstate();++/*+** Converts object to string, respecting any metamethods; returns NULL+** if an error occurs.+*/+const char *hsluaL_tolstring(lua_State *L, int index, size_t *len);++#endif
cbits/hslua/hslcall.c view
@@ -1,7 +1,7 @@ #include <HsFFI.h> #include <lua.h> #include <lauxlib.h>-#include "hslua-export.h"+#include "hslexport.h" #include "hslcall.h" #include "hsludata.h" @@ -71,7 +71,7 @@ ** function-wrapping userdata when it's been called and removes ** the userdata from the stack. */-void *hslua_hs_fun_ptr(lua_State *L)+void *hslua_extracthsfun(lua_State *L) { void *fn = luaL_testudata(L, 1, HSLUA_HSFUN_NAME); lua_remove(L, 1);@@ -84,10 +84,11 @@ */ void hslua_registerhsfunmetatable(lua_State *L) {- hslua_newudmetatable(L, HSLUA_HSFUN_NAME);- lua_pushcfunction(L, &hslua_call_wrapped_hs_fun);- lua_setfield(L, -2, "__call");- lua_pop(L, 1);+ if (hslua_newudmetatable(L, HSLUA_HSFUN_NAME)) {+ lua_pushcfunction(L, &hslua_callhsfun);+ lua_setfield(L, -2, "__call");+ lua_pop(L, 1);+ } } /*
+ cbits/hslua/hslexport.h view
@@ -0,0 +1,9 @@+/* ***************************************************************+ * Functions exported from Haskell+ * ***************************************************************/++#include <HsFFI.h>+#include <lua.h>++/* exported from Lua.Call */+int hslua_callhsfun(lua_State *L);
− cbits/hslua/hslua-export.h
@@ -1,8 +0,0 @@-/* ***************************************************************- * Functions exported from Haskell- * ***************************************************************/--#include <lua.h>--/* exported from Foreign.Lua.Raw.Call */-int hslua_call_wrapped_hs_fun(lua_State *L);
cbits/hslua/hslua.c view
@@ -19,6 +19,11 @@ return 1; } +/*+** Compares two values on the stack. Behaves mostly like lua_compare,+** but takes an additional parameter `status`, the referent of which is+** assigned the result of calling the helper function.+ */ int hslua_compare(lua_State *L, int index1, int index2, int op, int *status) { index1 = lua_absindex(L, index1);@@ -27,8 +32,11 @@ lua_pushvalue(L, index1); lua_pushvalue(L, index2); lua_pushinteger(L, op);- *status = lua_pcall(L, 3, 1, 0);- if (*status != LUA_OK) {+ int outcome = lua_pcall(L, 3, 1, 0);+ if (status != NULL) {+ *status = outcome;+ }+ if (outcome != LUA_OK) { return 0; } int result = lua_tointeger(L, -1);@@ -63,12 +71,13 @@ return 1; } -void hslua_getglobal(lua_State *L, const char *name, size_t len, int *status)+int hslua_getglobal(lua_State *L, const char *name, size_t len, int *status) { lua_pushcfunction(L, hslua__getglobal); lua_pushglobaltable(L); lua_pushlstring(L, name, len); *status = lua_pcall(L, 2, 1, 0);+ return lua_type(L, -1); } @@ -82,12 +91,13 @@ return 1; } -void hslua_gettable(lua_State *L, int index, int *status)+int hslua_gettable(lua_State *L, int index, int *status) { lua_pushvalue(L, index); lua_pushcfunction(L, hslua__gettable); lua_insert(L, -3); *status = lua_pcall(L, 2, 1, 0);+ return lua_type(L, -1); } @@ -157,49 +167,4 @@ } /* success */ return (lua_gettop(L) - oldsize + 1); /* correct for popped value */-}---/*-** Auxiliary Library-*/--/*-** newstate-*/-lua_State *hsluaL_newstate()-{- lua_State *L = luaL_newstate();-- /* add error value */- lua_createtable(L, 0, 0);- lua_setfield(L, LUA_REGISTRYINDEX, HSLUA_ERR);-- /* register HaskellFunction userdata metatable */- hslua_registerhsfunmetatable(L);-- return L;-}---/*-** tolstring'-*/-int hsluaL__tolstring(lua_State *L)-{- luaL_tolstring(L, 1, NULL);- return 1;-}--const char *hsluaL_tolstring(lua_State *L, int index, size_t *len)-{- lua_pushvalue(L, index);- lua_pushcfunction(L, hsluaL__tolstring);- lua_insert(L, -2);- int res = lua_pcall(L, 1, 1, 0);- if (res != 0) {- /* error */- return NULL;- }- return lua_tolstring(L, -1, len); }
cbits/hslua/hslua.h view
@@ -1,5 +1,4 @@-#include "lua.h"-#include "lauxlib.h"+#include <lua.h> int hslua_error(lua_State *L); @@ -11,23 +10,12 @@ void hslua_concat(lua_State *L, int n, int *status); -void hslua_getglobal(lua_State *L, const char *name, size_t len, int *status);+int hslua_getglobal(lua_State *L, const char *name, size_t len, int *status); -void hslua_gettable(lua_State *L, int index, int *status);+int hslua_gettable(lua_State *L, int index, int *status); void hslua_setglobal(lua_State *L, const char *k, size_t len, int *status); void hslua_settable(lua_State *L, int index, int *status); int hslua_next(lua_State *L, int index, int *status);---/* auxiliary library */-const char *hsluaL_tolstring(lua_State *L, int index, size_t *len);--/*-** function calling-*/--/* Wraps a Haskell function with an userdata object. */-void hslua_newhsfunwrapper(lua_State *L, HsStablePtr fn);
cbits/hslua/hsludata.c view
@@ -3,7 +3,7 @@ #include "hsludata.h" /* ***************************************************************- * Userdata Creation and Garbage Collection+ * Userdata for Haskell values * ***************************************************************/ /*@@ -24,6 +24,9 @@ /* ** Creates a new userdata metatable for Haskell objects, or gets ** is from the registry if possible.+**+** Returns `true` if the metatable was created, and `false` if it+** already existed and was fetched from the registry. */ int hslua_newudmetatable(lua_State *L, const char *tname) {
cbits/hslua/hsludata.h view
@@ -1,5 +1,6 @@ #include <HsFFI.h> #include <lua.h>+#include <lauxlib.h> /* *************************************************************** * Userdata for Haskell values
lua.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: lua-version: 1.0.0+version: 2.0.0 synopsis: Lua, an embeddable scripting language description: This package provides bindings and types to bridge Haskell and <https://www.lua.org/ Lua>.@@ -8,7 +8,7 @@ The full Lua interpreter version 5.3.6 is included. Alternatively, a system-wide Lua installation can be linked instead.-homepage: https://hslua.github.io/+homepage: https://hslua.org/ bug-reports: https://github.com/hslua/hslua/issues license: MIT license-file: LICENSE@@ -28,7 +28,8 @@ , GHC == 8.4.4 , GHC == 8.6.5 , GHC == 8.8.4- , GHC == 8.10.2+ , GHC == 8.10.4+ , GHC == 9.0.1 source-repository head type: git@@ -88,7 +89,6 @@ common common-options default-language: Haskell2010 build-depends: base >= 4.8 && < 5- , bytestring >= 0.10.2 && < 0.11 ghc-options: -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances@@ -102,15 +102,32 @@ -Wpartial-fields -fhide-source-paths + if flag(lua_32bits)+ cc-options: -DLUA_32BITS++ if flag(apicheck)+ cc-options: -DLUA_USE_APICHECK++ if flag(allow-unsafe-gc)+ cpp-options: -DALLOW_UNSAFE_GC++ if flag(hardcode-reg-keys)+ cpp-options: -DHARDCODE_REG_KEYS++ library import: common-options- exposed-modules: Foreign.Lua.Raw.Auxiliary- , Foreign.Lua.Raw.Call- , Foreign.Lua.Raw.Constants- , Foreign.Lua.Raw.Error- , Foreign.Lua.Raw.Functions- , Foreign.Lua.Raw.Types- , Foreign.Lua.Raw.Userdata+ exposed-modules: Lua+ , Lua.Auxiliary+ , Lua.Call+ , Lua.Constants+ , Lua.Ersatz+ , Lua.Ersatz.Auxiliary+ , Lua.Ersatz.Functions+ , Lua.Lib+ , Lua.Primary+ , Lua.Types+ , Lua.Userdata hs-source-dirs: src default-extensions: CApiFFI , ForeignFunctionInterface@@ -118,16 +135,23 @@ other-extensions: CPP , DeriveGeneric , GeneralizedNewtypeDeriving+ , PatternSynonyms c-sources: cbits/hslua/hsludata.c , cbits/hslua/hslcall.c+ , cbits/hslua/hslauxlib.c , cbits/hslua/hslua.c include-dirs: cbits/hslua+ includes: lua.h+ , luaconf.h+ , lauxlib.h+ install-includes: lua.h+ , luaconf.h+ , lauxlib.h if flag(system-lua) || flag(pkg-config) if flag(pkg-config) pkgconfig-depends: lua5.3 else extra-libraries: lua- includes: lua.h else include-dirs: cbits/lua-5.3.6 c-sources: cbits/lua-5.3.6/lapi.c@@ -178,23 +202,12 @@ if flag(export-dynamic) ld-options: -Wl,-E - if flag(lua_32bits)- cc-options: -DLUA_32BITS-- if flag(apicheck)- cc-options: -DLUA_USE_APICHECK-- if flag(allow-unsafe-gc)- cpp-options: -DALLOW_UNSAFE_GC-- if flag(hardcode-reg-keys)- cpp-options: -DHARDCODE_REG_KEYS- test-suite test-lua import: common-options type: exitcode-stdio-1.0 main-is: test-lua.hs hs-source-dirs: test+ other-modules: Lua.UnsafeTests build-depends: lua , tasty >= 0.11 , tasty-hunit >= 0.9
− src/Foreign/Lua/Raw/Auxiliary.hs
@@ -1,133 +0,0 @@-{-# LANGUAGE CPP #-}-{-|-Module : Foreign.Lua.Raw.Auxiliary-Copyright : © 2007–2012 Gracjan Polak;- © 2012–2016 Ömer Sinan Ağacan;- © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : non-portable (depends on GHC)--Raw bindings to functions and constants of the auxiliary library.--}-module Foreign.Lua.Raw.Auxiliary- ( hsluaL_newstate- , hsluaL_tolstring- , luaL_getmetafield- , luaL_getmetatable- , luaL_loadbuffer- , luaL_newmetatable- , luaL_ref- , luaL_testudata- , luaL_traceback- , luaL_unref- -- * Registry fields- , loadedTableRegistryField- , preloadTableRegistryField- -- * References- , Reference (..)- , fromReference- , toReference- ) where--import Foreign.C (CChar, CInt (CInt), CSize (CSize), CString)-import Foreign.Lua.Raw.Types (StackIndex)-import Foreign.Ptr-import qualified Foreign.Lua.Raw.Types as Lua--#ifndef HARDCODE_REG_KEYS-import System.IO.Unsafe (unsafePerformIO)-import qualified Foreign.C as C-#endif--#ifdef ALLOW_UNSAFE_GC-#define SAFTY unsafe-#else-#define SAFTY safe-#endif---- * The Auxiliary Library---- | Key, in the registry, for table of loaded modules.-loadedTableRegistryField :: String-#ifdef HARDCODE_REG_KEYS-loadedTableRegistryField = "_LOADED"-#else-loadedTableRegistryField = unsafePerformIO (C.peekCString c_loaded_table)-{-# NOINLINE loadedTableRegistryField #-}--foreign import capi unsafe "lauxlib.h value LUA_LOADED_TABLE"- c_loaded_table :: CString-#endif---- | Key, in the registry, for table of preloaded loaders.-preloadTableRegistryField :: String-#ifdef HARDCODE_REG_KEYS-preloadTableRegistryField = "_PRELOAD"-#else-preloadTableRegistryField = unsafePerformIO (C.peekCString c_preload_table)-{-# NOINLINE preloadTableRegistryField #-}--foreign import capi unsafe "lauxlib.h value LUA_PRELOAD_TABLE"- c_preload_table :: CString-#endif--foreign import capi SAFTY "lauxlib.h luaL_getmetafield"- luaL_getmetafield :: Lua.State -> StackIndex -> CString -> IO Lua.TypeCode--foreign import capi SAFTY "lauxlib.h luaL_getmetatable"- luaL_getmetatable :: Lua.State -> CString -> IO Lua.TypeCode--foreign import capi SAFTY "lauxlib.h luaL_loadbuffer"- luaL_loadbuffer :: Lua.State -> Ptr CChar -> CSize -> CString- -> IO Lua.StatusCode--foreign import ccall SAFTY "lauxlib.h luaL_newmetatable"- luaL_newmetatable :: Lua.State -> CString -> IO Lua.LuaBool--foreign import ccall unsafe "lauxlib.h hsluaL_newstate"- hsluaL_newstate :: IO Lua.State--foreign import ccall SAFTY "lauxlib.h luaL_ref"- luaL_ref :: Lua.State -> StackIndex -> IO CInt--foreign import ccall safe "hslua.h hsluaL_tolstring"- hsluaL_tolstring :: Lua.State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)--foreign import capi SAFTY "lauxlib.h luaL_traceback"- luaL_traceback :: Lua.State -> Lua.State -> CString -> CInt -> IO ()--foreign import ccall SAFTY "lauxlib.h luaL_unref"- luaL_unref :: Lua.State -> StackIndex -> CInt -> IO ()---- | See--- <https://www.lua.org/manual/5.3/manual.html#luaL_testudata luaL_testudata>-foreign import capi SAFTY "lauxlib.h luaL_testudata"- luaL_testudata :: Lua.State -> StackIndex -> CString -> IO (Ptr ())------- References------- | Reference to a stored value.-data Reference =- Reference CInt -- ^ Reference to a stored value- | RefNil -- ^ Reference to a nil value- deriving (Eq, Show)--foreign import capi SAFTY "lauxlib.h value LUA_REFNIL"- refnil :: CInt---- | Convert a reference to its C representation.-fromReference :: Reference -> CInt-fromReference = \case- Reference x -> x- RefNil -> refnil---- | Create a reference from its C representation.-toReference :: CInt -> Reference-toReference x =- if x == refnil- then RefNil- else Reference x
− src/Foreign/Lua/Raw/Call.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE CPP #-}-{-|-Module : Foreign.Lua.Raw.Call-Copyright : © 2007–2012 Gracjan Polak;- © 2012–2016 Ömer Sinan Ağacan;- © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : non-portable (depends on GHC)--Raw bindings to function call helpers.--}-module Foreign.Lua.Raw.Call- ( HsFunction- , hslua_newhsfunction- , hslua_pushhsfunction- ) where--import Foreign.C (CInt (CInt))-import Foreign.Ptr (Ptr, castPtr, nullPtr)-import Foreign.StablePtr (StablePtr, deRefStablePtr, newStablePtr)-import Foreign.Storable (peek)-import Foreign.Lua.Raw.Types- ( NumResults (NumResults)- , State (State)- )--#ifdef ALLOW_UNSAFE_GC-#define SAFTY unsafe-#else-#define SAFTY safe-#endif---- | Type of raw Haskell functions that can be made into--- 'CFunction's.-type HsFunction = State -> IO NumResults---- | Retrieve the pointer to a Haskell function from the wrapping--- userdata object.-foreign import ccall SAFTY "hslua.h hslua_hs_fun_ptr"- hslua_hs_fun_ptr :: State -> IO (Ptr ())---- | Pushes a new C function created from an 'HsFunction'.-foreign import ccall SAFTY "hslua.h hslua_newhsfunction"- hslua_newhsfunction :: State -> StablePtr a -> IO ()--hslua_pushhsfunction :: State -> HsFunction -> IO ()-hslua_pushhsfunction l preCFn =- newStablePtr preCFn >>= hslua_newhsfunction l-{-# INLINABLE hslua_pushhsfunction #-}---- | Call the Haskell function stored in the userdata. This--- function is exported as a C function, as the C code uses it as--- the @__call@ value of the wrapping userdata metatable.-hslua_call_wrapped_hs_fun :: HsFunction-hslua_call_wrapped_hs_fun l = do- udPtr <- hslua_hs_fun_ptr l- if udPtr == nullPtr- then error "Cannot call function; corrupted Lua object!"- else do- fn <- peek (castPtr udPtr) >>= deRefStablePtr- fn l--foreign export ccall hslua_call_wrapped_hs_fun :: HsFunction
− src/Foreign/Lua/Raw/Constants.hs
@@ -1,39 +0,0 @@-{-|-Module : Foreign.Lua.Raw.Constants-Copyright : © 2007–2012 Gracjan Polak;- © 2012–2016 Ömer Sinan Ağacan;- © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : ForeignFunctionInterface--Lua constants--}-module Foreign.Lua.Raw.Constants- ( multret- , registryindex- , refnil- , noref- ) where--import Foreign.C (CInt (..))-import Foreign.Lua.Raw.Types---- | Alias for C constant @LUA_MULTRET@. See--- <https://www.lua.org/manual/5.3/#lua_call lua_call>.-foreign import capi unsafe "lua.h value LUA_MULTRET"- multret :: NumResults---- | Alias for C constant @LUA_REGISTRYINDEX@. See--- <https://www.lua.org/manual/5.3/#3.5 Lua registry>.-foreign import capi unsafe "lua.h value LUA_REGISTRYINDEX"- registryindex :: StackIndex---- | Value signaling that no reference was created.-foreign import capi unsafe "lauxlib.h value LUA_REFNIL"- refnil :: Int---- | Value signaling that no reference was found.-foreign import capi unsafe "lauxlib.h value LUA_NOREF"- noref :: Int
− src/Foreign/Lua/Raw/Error.hs
@@ -1,40 +0,0 @@-{-|-Module : Foreign.Lua.Raw.Error-Copyright : © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : portable--Lua exceptions and exception handling.--}-module Foreign.Lua.Raw.Error- ( -- * Passing Lua errors to Haskell- errorMessage- ) where--import Data.ByteString (ByteString)-import Foreign.Lua.Raw.Auxiliary (hsluaL_tolstring)-import Foreign.Lua.Raw.Functions (lua_pop)-import Foreign.Marshal.Alloc (alloca)-import Foreign.Ptr (nullPtr)--import qualified Data.ByteString as B-import qualified Data.ByteString.Char8 as Char8-import qualified Foreign.Storable as Storable-import qualified Foreign.Lua.Raw.Types as Lua---- | Retrieve and pop the top object as an error message. This is very similar--- to tostring', but ensures that we don't recurse if getting the message--- failed.-errorMessage :: Lua.State -> IO ByteString-errorMessage l = alloca $ \lenPtr -> do- cstr <- hsluaL_tolstring l (-1) lenPtr- if cstr == nullPtr- then return $ Char8.pack ("An error occurred, but the error object " ++- "cannot be converted into a string.")- else do- cstrLen <- Storable.peek lenPtr- msg <- B.packCStringLen (cstr, fromIntegral cstrLen)- lua_pop l 2- return msg
− src/Foreign/Lua/Raw/Functions.hs
@@ -1,403 +0,0 @@-{-# LANGUAGE CPP #-}-{-|-Module : Foreign.Lua.Raw.Functions-Copyright : © 2007–2012 Gracjan Polak;- © 2012–2016 Ömer Sinan Ağacan;- © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : ForeignFunctionInterface, CPP--Haskell bindings to Lua C API functions.--The exposed functions correspond closely to the respective C Lua API-functions. However, C API functions which can throw Lua errors are not-exported directly, as any errors would crash the program. Non-error-throwing @hslua_@ versions are provided instead. The @hslua@ ersatz-functions have worse performance than the original.--Some of the Lua functions may, directly or indirectly, call a Haskell-function, and trigger garbage collection, rescheduling etc. These-functions are always imported safely (i.e., with the @safe@ keyword).--However, all function can trigger garbage collection. If that can lead-to problems, then the package should be configured without flag-@allow-unsafe-gc@.--}-module Foreign.Lua.Raw.Functions where--import Foreign.C-import Foreign.Lua.Raw.Types as Lua-import Foreign.Ptr--#ifdef ALLOW_UNSAFE_GC-#define SAFTY unsafe-#else-#define SAFTY safe-#endif---- * State manipulation---- | Wrapper of @lua_close@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_close>.-foreign import ccall safe "lua.h lua_close"- lua_close :: Lua.State -> IO ()----- * Basic stack manipulation---- | Wrapper of @lua_absindex@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_absindex>.-foreign import ccall SAFTY "lua.h lua_absindex"- lua_absindex :: Lua.State -> StackIndex -> IO StackIndex---- | Wrapper of @lua_gettop@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_gettop>.-foreign import ccall SAFTY "lua.h lua_gettop"- lua_gettop :: Lua.State -> IO StackIndex---- | Wrapper of @lua_settop@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_settop>.-foreign import ccall SAFTY "lua.h lua_settop"- lua_settop :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_pushvalue@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushvalue>.-foreign import ccall SAFTY "lua.h lua_pushvalue"- lua_pushvalue :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_pop@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pop>.-foreign import capi SAFTY "lua.h lua_pop"- lua_pop :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_copy@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_copy>.-foreign import ccall SAFTY "lua.h lua_copy"- lua_copy :: Lua.State -> StackIndex -> StackIndex -> IO ()---- | Wrapper of @lua_remove@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_remove>.-foreign import capi SAFTY "lua.h lua_remove"- lua_remove :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_insert@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_insert>.-foreign import capi SAFTY "lua.h lua_insert"- lua_insert :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_replace@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_replace>.-foreign import capi SAFTY "lua.h lua_replace"- lua_replace :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_checkstack@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_checkstack>.-foreign import capi SAFTY "lua.h lua_checkstack"- lua_checkstack :: Lua.State -> CInt -> IO LuaBool----- * Access functions (stack -> Haskell)---- | Wrapper of @lua_isnumber@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_isnumber>.-foreign import ccall SAFTY "lua.h lua_isnumber"- lua_isnumber :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper of @lua_isinteger@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_isinteger>.-foreign import ccall SAFTY "lua.h lua_isinteger"- lua_isinteger :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper of @lua_isstring@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_isstring>.-foreign import ccall SAFTY "lua.h lua_isstring"- lua_isstring :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper of @lua_iscfunction@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_iscfunction>.-foreign import ccall SAFTY "lua.h lua_iscfunction"- lua_iscfunction :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper of @lua_isuserdata@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_isuserdata>.-foreign import ccall SAFTY "lua.h lua_isuserdata"- lua_isuserdata :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper of @lua_type@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_type>.-foreign import ccall SAFTY "lua.h lua_type"- lua_type :: Lua.State -> StackIndex -> IO TypeCode---- | Wrapper of @lua_typename@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_typename>.-foreign import ccall SAFTY "lua.h lua_typename"- lua_typename :: Lua.State -> TypeCode -> IO CString---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_compare \--- @lua_compare@> which catches any Lua errors.-foreign import capi safe "hslua.h hslua_compare"- hslua_compare :: Lua.State- -> StackIndex -> StackIndex -> CInt- -> Ptr StatusCode -> IO LuaBool---- | Wrapper of @lua_rawequal@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_rawequal>.-foreign import ccall SAFTY "lua.h lua_rawequal"- lua_rawequal :: Lua.State -> StackIndex -> StackIndex -> IO LuaBool----- | Wrapper of @lua_toboolean@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_toboolean>.-foreign import capi SAFTY "lua.h lua_toboolean"- lua_toboolean :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper of @lua_tocfunction@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_tocfunction>.-foreign import ccall SAFTY "lua.h lua_tocfunction"- lua_tocfunction :: Lua.State -> StackIndex -> IO CFunction---- | Wrapper of @lua_tointegerx@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_tointegerx>.-foreign import ccall SAFTY "lua.h lua_tointegerx"- lua_tointegerx :: Lua.State -> StackIndex -> Ptr LuaBool -> IO Lua.Integer---- | Wrapper of @lua_tonumberx@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_tonumberx>.-foreign import ccall SAFTY "lua.h lua_tonumberx"- lua_tonumberx :: Lua.State -> StackIndex -> Ptr LuaBool -> IO Lua.Number---- | Wrapper of @lua_tolstring@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_tolstring>.-foreign import ccall SAFTY "lua.h lua_tolstring"- lua_tolstring :: Lua.State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)---- | Wrapper of @lua_topointer@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_topointer>.-foreign import ccall SAFTY "lua.h lua_topointer"- lua_topointer :: Lua.State -> StackIndex -> IO (Ptr ())---- | Wrapper of @lua_tothread@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_tothread>.-foreign import ccall SAFTY "lua.h lua_tothread"- lua_tothread :: Lua.State -> StackIndex -> IO Lua.State---- | Wrapper of @lua_touserdata@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_touserdata>.-foreign import ccall SAFTY "lua.h lua_touserdata"- lua_touserdata :: Lua.State -> StackIndex -> IO (Ptr a)----- | Wrapper of @lua_rawlen@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_rawlen>.-foreign import ccall SAFTY "lua.h lua_rawlen"- lua_rawlen :: Lua.State -> StackIndex -> IO CSize----- * Push functions (Haskell -> stack)---- | Wrapper of @lua_pushnil@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushnil>.-foreign import ccall SAFTY "lua.h lua_pushnil"- lua_pushnil :: Lua.State -> IO ()---- | Wrapper of @lua_pushnumber@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushnumber>.-foreign import ccall SAFTY "lua.h lua_pushnumber"- lua_pushnumber :: Lua.State -> Lua.Number -> IO ()---- | Wrapper of @lua_pushinteger@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushinteger>.-foreign import ccall SAFTY "lua.h lua_pushinteger"- lua_pushinteger :: Lua.State -> Lua.Integer -> IO ()---- | Wrapper of @lua_pushlstring@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushlstring>.-foreign import ccall SAFTY "lua.h lua_pushlstring"- lua_pushlstring :: Lua.State -> Ptr CChar -> CSize -> IO ()---- | Wrapper of @lua_pushcclosure@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushcclosure>.-foreign import ccall SAFTY "lua.h lua_pushcclosure"- lua_pushcclosure :: Lua.State -> CFunction -> NumArgs -> IO ()---- | Wrapper of @lua_pushboolean@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushboolean>.-foreign import ccall SAFTY "lua.h lua_pushboolean"- lua_pushboolean :: Lua.State -> LuaBool -> IO ()---- | Wrapper of @lua_pushlightuserdata@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushlightuserdata>.-foreign import ccall SAFTY "lua.h lua_pushlightuserdata"- lua_pushlightuserdata :: Lua.State -> Ptr a -> IO ()---- | Wrapper of @lua_pushthread@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushthread>.-foreign import ccall SAFTY "lua.h lua_pushthread"- lua_pushthread :: Lua.State -> IO CInt----- * Get functions (Lua -> stack)---- | Wrapper around--- <https://lua.org/manual/5.3/manual.html#lua_gettable lua_gettable>.--- which catches any Lua errors.-foreign import ccall safe "hslua.h hslua_gettable"- hslua_gettable :: Lua.State -> StackIndex -> Ptr StatusCode -> IO ()---- | Wrapper of @lua_rawget@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_rawget>.-foreign import ccall SAFTY "lua.h lua_rawget"- lua_rawget :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_rawgeti@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_rawgeti>.-foreign import ccall SAFTY "lua.h lua_rawgeti"- lua_rawgeti :: Lua.State -> StackIndex -> Lua.Integer -> IO ()---- | Wrapper of @lua_createtable@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_createtable>.-foreign import ccall SAFTY "lua.h lua_createtable"- lua_createtable :: Lua.State -> CInt -> CInt -> IO ()---- | Wrapper of @lua_newuserdata@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_newuserdata>.-foreign import ccall SAFTY "lua.h lua_newuserdata"- lua_newuserdata :: Lua.State -> CSize -> IO (Ptr ())---- | Wrapper of @lua_getmetatable@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_getmetatable>.-foreign import ccall SAFTY "lua.h lua_getmetatable"- lua_getmetatable :: Lua.State -> StackIndex -> IO LuaBool---- | Wrapper around--- <https://lua.org/manual/5.3/manual.html#lua_getglobal lua_getglobal>--- which catches any Lua errors.-foreign import ccall safe "hslua.h hslua_getglobal"- hslua_getglobal :: Lua.State -> CString -> CSize -> Ptr StatusCode -> IO ()----- * Set functions (stack -> Lua)---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_settable \--- @lua_settable@> which catches any Lua errors.-foreign import ccall safe "hslua.h hslua_settable"- hslua_settable :: Lua.State -> StackIndex -> Ptr StatusCode -> IO ()---- | Wrapper of @lua_rawset@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_rawset>.-foreign import ccall SAFTY "lua.h lua_rawset"- lua_rawset :: Lua.State -> StackIndex -> IO ()---- | Wrapper of @lua_rawseti@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_rawseti>.-foreign import ccall SAFTY "lua.h lua_rawseti"- lua_rawseti :: Lua.State -> StackIndex -> Lua.Integer -> IO ()---- | Wrapper of @lua_setmetatable@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_setmetatable>.-foreign import ccall SAFTY "lua.h lua_setmetatable"- lua_setmetatable :: Lua.State -> StackIndex -> IO ()---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_setglobal \--- @lua_setglobal@> which catches any Lua errors.-foreign import ccall safe "hslua.h hslua_setglobal"- hslua_setglobal :: Lua.State -> CString -> CSize -> Ptr StatusCode -> IO ()----- * \'load\' and \'call\' functions (load and run Lua code)---- | Wrapper of @lua_pcall@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pcall>.-foreign import capi safe "lua.h lua_pcall"- lua_pcall :: Lua.State -> NumArgs -> NumResults -> StackIndex- -> IO StatusCode---- | Wrapper of @lua_load@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_load>.-foreign import ccall safe "lua.h lua_load"- lua_load :: Lua.State -> Lua.Reader -> Ptr () -> CString -> CString- -> IO StatusCode----- * Coroutine functions---- | Wrapper of @lua_status@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_status>.-foreign import ccall SAFTY "lua.h lua_status"- lua_status :: Lua.State -> IO StatusCode----- * Garbage-collection functions and options---- | Wrapper of @lua_gc@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_gc>.-foreign import ccall safe "lua.h lua_gc"- lua_gc :: Lua.State -> CInt -> CInt -> IO CInt----- * Miscellaneous functions---- | Replacement for--- <https://lua.org/manual/5.3/manual.html#lua_error lua_error>; it uses--- the HsLua error signaling convention instead of raw Lua errors.-foreign import ccall SAFTY "hslua.h hslua_error"- hslua_error :: Lua.State -> IO NumResults---- | Wrapper around--- <https://lua.org/manual/5.3/manual.html#lua_next lua_next> which--- catches any Lua errors.-foreign import ccall safe "hslua.h hslua_next"- hslua_next :: Lua.State -> StackIndex -> Ptr StatusCode -> IO LuaBool---- | Wrapper around--- <https://lua.org/manual/5.3/manual.html#lua_concat lua_concat>--- which catches any Lua errors.-foreign import ccall safe "hslua.h hslua_concat"- hslua_concat :: Lua.State -> NumArgs -> Ptr StatusCode -> IO ()---- | Wrapper of @lua_pushglobaltable@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#lua_pushglobaltable>.-foreign import capi SAFTY "lua.h lua_pushglobaltable"- lua_pushglobaltable :: Lua.State -> IO ()----- * Lua Libraries---- | Wrapper of @luaL_openlibs@. See the Lua docs at--- <https://www.lua.org/manual/5.3/manual.html#luaL_openlibs>.-foreign import ccall unsafe "lualib.h luaL_openlibs"- luaL_openlibs :: Lua.State -> IO ()---- | Point to function opening the base library.-foreign import ccall unsafe "lualib.h &luaopen_base"- lua_open_base_ptr :: CFunction---- | Point to function opening the table library.-foreign import ccall unsafe "lualib.h &luaopen_table"- lua_open_table_ptr :: CFunction---- | Point to function opening the io library.-foreign import ccall unsafe "lualib.h &luaopen_io"- lua_open_io_ptr :: CFunction---- | Point to function opening the os library.-foreign import ccall unsafe "lualib.h &luaopen_os"- lua_open_os_ptr :: CFunction---- | Point to function opening the string library.-foreign import ccall unsafe "lualib.h &luaopen_string"- lua_open_string_ptr :: CFunction---- | Point to function opening the math library.-foreign import ccall unsafe "lualib.h &luaopen_math"- lua_open_math_ptr :: CFunction---- | Point to function opening the debug library.-foreign import ccall unsafe "lualib.h &luaopen_debug"- lua_open_debug_ptr :: CFunction---- | Point to function opening the package library.-foreign import ccall unsafe "lualib.h &luaopen_package"- lua_open_package_ptr :: CFunction
− src/Foreign/Lua/Raw/Types.hsc
@@ -1,281 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-|-Module : Foreign.Lua.Raw.Types-Copyright : © 2007–2012 Gracjan Polak;- © 2012–2016 Ömer Sinan Ağacan;- © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : non-portable (depends on GHC)--The core Lua types, including mappings of Lua types to Haskell.--}-module Foreign.Lua.Raw.Types- ( State (..)- , Reader- , GCCONTROL (..)- , Type (..)- , TypeCode (..)- , fromType- , toType- , CFunction- , LuaBool (..)- , false- , true- , fromLuaBool- , toLuaBool- , Integer (..)- , Number (..)- , StackIndex (..)- , NumArgs (..)- , NumResults (..)- , RelationalOperator (..)- , fromRelationalOperator- , Status (..)- , StatusCode (..)- , toStatus- ) where--#include "lua.h"--- required only for LUA_ERRFILE-#include "lauxlib.h"--import Prelude hiding (Integer, EQ, LT)--import Data.Int (#{type LUA_INTEGER})-import Foreign.C (CChar, CInt, CSize)-import Foreign.Ptr (FunPtr, Ptr)-import Foreign.Storable (Storable)-import GHC.Generics (Generic)---- | An opaque structure that points to a thread and indirectly (through the--- thread) to the whole state of a Lua interpreter. The Lua library is fully--- reentrant: it has no global variables. All information about a state is--- accessible through this structure.------ Synonym for @lua_State *@. See <https://www.lua.org/manual/5.3/#lua_State lua_State>.-newtype State = State (Ptr ()) deriving (Eq, Generic)---- | Type for C functions.------ In order to communicate properly with Lua, a C function must use the--- following protocol, which defines the way parameters and results are--- passed: a C function receives its arguments from Lua in its stack in--- direct order (the first argument is pushed first). So, when the--- function starts, @'Foreign.Lua.Core.Functions.gettop'@ returns the--- number of arguments received by the function. The first argument (if--- any) is at index 1 and its last argument is at index--- @'Foreign.Lua.Core.Functions.gettop'@. To return values to Lua, a C--- function just pushes them onto the stack, in direct order (the first--- result is pushed first), and returns the number of results. Any other--- value in the stack below the results will be properly discarded by--- Lua. Like a Lua function, a C function called by Lua can also return--- many results.------ See <https://www.lua.org/manual/5.3/manual.html#lua_CFunction lua_CFunction>.-type CFunction = FunPtr (State -> IO NumResults)---- | The reader function used by @'Foreign.Lua.Core.Functions.load'@.--- Every time it needs another piece of the chunk, lua_load calls the--- reader, passing along its data parameter. The reader must return a--- pointer to a block of memory with a new piece of the chunk and set--- size to the block size. The block must exist until the reader--- function is called again. To signal the end of the chunk, the reader--- must return @NULL@ or set size to zero. The reader function may--- return pieces of any size greater than zero.------ See <https://www.lua.org/manual/5.3/manual.html#lua_Reader lua_Reader>.-type Reader = FunPtr (State -> Ptr () -> Ptr CSize -> IO (Ptr CChar))---- | The type of integers in Lua.------ By default this type is @'Int64'@, but that can be changed to different--- values in lua. (See @LUA_INT_TYPE@ in @luaconf.h@.)------ See <https://www.lua.org/manual/5.3/manual.html#lua_Integer lua_Integer>.-newtype Integer = Integer #{type LUA_INTEGER}- deriving (Bounded, Enum, Eq, Integral, Num, Ord, Real, Show)---- | The type of floats in Lua.------ By default this type is @'Double'@, but that can be changed in Lua to a--- single float or a long double. (See @LUA_FLOAT_TYPE@ in @luaconf.h@.)------ See <https://www.lua.org/manual/5.3/manual.html#lua_Number lua_Number>.-newtype Number = Number #{type LUA_NUMBER}- deriving (Eq, Floating, Fractional, Num, Ord, Real, RealFloat, RealFrac, Show)-------- LuaBool------- | Boolean value returned by a Lua C API function. This is a @'CInt'@ and--- interpreted as @'False'@ iff the value is @0@, @'True'@ otherwise.-newtype LuaBool = LuaBool CInt- deriving (Eq, Storable, Show)---- | Generic Lua representation of a value interpreted as being true.-true :: LuaBool-true = LuaBool 1---- | Lua representation of the value interpreted as false.-false :: LuaBool-false = LuaBool 0---- | Convert a @'LuaBool'@ to a Haskell @'Bool'@.-fromLuaBool :: LuaBool -> Bool-fromLuaBool (LuaBool 0) = False-fromLuaBool _ = True-{-# INLINABLE fromLuaBool #-}---- | Convert a Haskell @'Bool'@ to a @'LuaBool'@.-toLuaBool :: Bool -> LuaBool-toLuaBool True = true-toLuaBool False = false-{-# INLINABLE toLuaBool #-}-------- * Type of Lua values------- | Enumeration used as type tag.--- See <https://www.lua.org/manual/5.3/manual.html#lua_type lua_type>.-data Type- = TypeNone -- ^ non-valid stack index- | TypeNil -- ^ type of lua's @nil@ value- | TypeBoolean -- ^ type of lua booleans- | TypeLightUserdata -- ^ type of light userdata- | TypeNumber -- ^ type of lua numbers. See @'Lua.Number'@- | TypeString -- ^ type of lua string values- | TypeTable -- ^ type of lua tables- | TypeFunction -- ^ type of functions, either normal or @'CFunction'@- | TypeUserdata -- ^ type of full user data- | TypeThread -- ^ type of lua threads- deriving (Bounded, Eq, Ord, Show)---- | Integer code used to encode the type of a lua value.-newtype TypeCode = TypeCode { fromTypeCode :: CInt }- deriving (Eq, Ord, Show)--instance Enum Type where- fromEnum = fromIntegral . fromTypeCode . fromType- toEnum = toType . TypeCode . fromIntegral---- | Convert a lua Type to a type code which can be passed to the C API.-fromType :: Type -> TypeCode-fromType tp = TypeCode $ case tp of- TypeNone -> #{const LUA_TNONE}- TypeNil -> #{const LUA_TNIL}- TypeBoolean -> #{const LUA_TBOOLEAN}- TypeLightUserdata -> #{const LUA_TLIGHTUSERDATA}- TypeNumber -> #{const LUA_TNUMBER}- TypeString -> #{const LUA_TSTRING}- TypeTable -> #{const LUA_TTABLE}- TypeFunction -> #{const LUA_TFUNCTION}- TypeUserdata -> #{const LUA_TUSERDATA}- TypeThread -> #{const LUA_TTHREAD}---- | Convert numerical code to lua type.-toType :: TypeCode -> Type-toType (TypeCode c) = case c of- #{const LUA_TNONE} -> TypeNone- #{const LUA_TNIL} -> TypeNil- #{const LUA_TBOOLEAN} -> TypeBoolean- #{const LUA_TLIGHTUSERDATA} -> TypeLightUserdata- #{const LUA_TNUMBER} -> TypeNumber- #{const LUA_TSTRING} -> TypeString- #{const LUA_TTABLE} -> TypeTable- #{const LUA_TFUNCTION} -> TypeFunction- #{const LUA_TUSERDATA} -> TypeUserdata- #{const LUA_TTHREAD} -> TypeThread- _ -> error ("No Type corresponding to " ++ show c)------- * Relational Operator------- | Lua comparison operations.-data RelationalOperator- = EQ -- ^ Correponds to lua's equality (==) operator.- | LT -- ^ Correponds to lua's strictly-lesser-than (<) operator- | LE -- ^ Correponds to lua's lesser-or-equal (<=) operator- deriving (Eq, Ord, Show)---- | Convert relation operator to its C representation.-fromRelationalOperator :: RelationalOperator -> CInt-fromRelationalOperator EQ = #{const LUA_OPEQ}-fromRelationalOperator LT = #{const LUA_OPLT}-fromRelationalOperator LE = #{const LUA_OPLE}-{-# INLINABLE fromRelationalOperator #-}-------- * Status------- | Lua status values.-data Status- = OK -- ^ success- | Yield -- ^ yielding / suspended coroutine- | ErrRun -- ^ a runtime rror- | ErrSyntax -- ^ syntax error during precompilation- | ErrMem -- ^ memory allocation (out-of-memory) error.- | ErrErr -- ^ error while running the message handler.- | ErrGcmm -- ^ error while running a @__gc@ metamethod.- | ErrFile -- ^ opening or reading a file failed.- deriving (Eq, Show)---- | Convert C integer constant to @'Status'@.-toStatus :: StatusCode -> Status-toStatus (StatusCode c) = case c of- #{const LUA_OK} -> OK- #{const LUA_YIELD} -> Yield- #{const LUA_ERRRUN} -> ErrRun- #{const LUA_ERRSYNTAX} -> ErrSyntax- #{const LUA_ERRMEM} -> ErrMem- #{const LUA_ERRGCMM} -> ErrGcmm- #{const LUA_ERRERR} -> ErrErr- #{const LUA_ERRFILE} -> ErrFile- n -> error $ "Cannot convert (" ++ show n ++ ") to Status"-{-# INLINABLE toStatus #-}---- | Integer code used to signal the status of a thread or computation.--- See @'Status'@.-newtype StatusCode = StatusCode CInt deriving (Eq, Storable)-------- * Gargabe Collection Control------- | Enumeration used by @gc@ function.-data GCCONTROL- = GCSTOP- | GCRESTART- | GCCOLLECT- | GCCOUNT- | GCCOUNTB- | GCSTEP- | GCSETPAUSE- | GCSETSTEPMUL- deriving (Enum, Eq, Ord, Show)---- | A stack index-newtype StackIndex = StackIndex { fromStackIndex :: CInt }- deriving (Enum, Eq, Num, Ord, Show)------- Number of arguments and return values------- | The number of arguments consumed curing a function call.-newtype NumArgs = NumArgs { fromNumArgs :: CInt }- deriving (Eq, Num, Ord, Show)---- | The number of results returned by a function call.-newtype NumResults = NumResults { fromNumResults :: CInt }- deriving (Eq, Num, Ord, Show)
− src/Foreign/Lua/Raw/Userdata.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE CPP #-}-{-|-Module : Foreign.Lua.Raw.Userdata-Copyright : © 2017-2021 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : ForeignFunctionInterface--Bindings to HsLua-specific functions used to push Haskell values-as userdata.--}-module Foreign.Lua.Raw.Userdata- ( hslua_fromuserdata- , hslua_newhsuserdata- , hslua_newudmetatable- ) where--import Foreign.C (CInt (CInt), CString)-import Foreign.Lua.Raw.Auxiliary (luaL_testudata)-import Foreign.Lua.Raw.Functions (lua_newuserdata)-import Foreign.Lua.Raw.Types- ( LuaBool (..)- , StackIndex (..)- , State (..)- )-import Foreign.Ptr (castPtr, nullPtr)-import Foreign.StablePtr (newStablePtr, deRefStablePtr)-import Foreign.Storable (peek, poke, sizeOf)--#ifdef ALLOW_UNSAFE_GC-#define SAFTY unsafe-#else-#define SAFTY safe-#endif---- | Creates and registers a new metatable for a userdata-wrapped--- Haskell value; checks whether a metatable of that name has been--- registered yet and uses the registered table if possible.-foreign import ccall SAFTY "hsludata.h hslua_newudmetatable"- hslua_newudmetatable :: State -- ^ Lua state- -> CString -- ^ Userdata name (__name)- -> IO LuaBool -- ^ True iff new metatable- -- was created.---- | Creates a new userdata wrapping the given Haskell object.-hslua_newhsuserdata :: State -> a -> IO ()-hslua_newhsuserdata l x = do- xPtr <- newStablePtr x- udPtr <- lua_newuserdata l (fromIntegral $ sizeOf xPtr)- poke (castPtr udPtr) xPtr-{-# INLINABLE hslua_newhsuserdata #-}---- | Retrieves a Haskell object from userdata at the given index.--- The userdata /must/ have the given name.-hslua_fromuserdata :: State- -> StackIndex -- ^ userdata index- -> CString -- ^ name- -> IO (Maybe a)-hslua_fromuserdata l idx name = do- udPtr <- luaL_testudata l idx name- if udPtr == nullPtr- then return Nothing- else Just <$> (peek (castPtr udPtr) >>= deRefStablePtr)-{-# INLINABLE hslua_fromuserdata #-}
+ src/Lua.hs view
@@ -0,0 +1,293 @@+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}+{-# LANGUAGE PatternSynonyms #-}+{-|+Module : Lua+Copyright : © 2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : portable++Extend Haskell programs with a Lua interpreter.++This package provides the basic building blocks to integrate Lua into a+Haskell program. The library is kept very close to the C Lua API, and+users familiar with the C API should have no problem using it.++However, there are important differences of which users must be aware:+The method for error signaling used in Lua, based on @setjmp@ and+@longjmp@, is incompatible with the Haskell FFI. All errors /must/ be+handled at language boundaries, as failure to do so will lead to+unrecoverable crashes. C API functions that can throw Lua errors are+still exported, but non-error throwing @hslua_@ versions are provided as+safer alternatives. . The @hslua@ ersatz functions have worse+performance than the original versions, but should be fast enough for+most use cases.++The Haskell FFI requires all C function that can call back into Haskell+to be imported @safe@ly. Some of the Lua functions may, directly or+indirectly, call a Haskell function, so they are always imported with+the @safe@ keyword.++Many API functions can trigger garbage collection. This will lead to+problems if Haskell functions are used as part of finalizers (i.e.,+@__gc@ metamethods). Haskell in finalizers is not supported by default,+but can be enabled by unsetting the @allow-unsafe-gc@ flag.+-}+module Lua+ ( -- * Run Lua operations+ withNewState+ -- * Types+ , State (..)+ , Reader+ -- ** Base Lua types+ , CFunction+ , PreCFunction+ , Lua.Integer (..)+ , Number (..)+ -- *** Booleans+ , LuaBool (..)+ , pattern TRUE+ , pattern FALSE+ -- ** Stack indices+ , StackIndex (..)+ , pattern LUA_REGISTRYINDEX+ -- ** Function calling+ , NumArgs (..)+ , NumResults (..)+ , pattern LUA_MULTRET+ -- ** Basic types+ , TypeCode (..)+ , pattern LUA_TNONE+ , pattern LUA_TNIL+ , pattern LUA_TBOOLEAN+ , pattern LUA_TLIGHTUSERDATA+ , pattern LUA_TNUMBER+ , pattern LUA_TSTRING+ , pattern LUA_TTABLE+ , pattern LUA_TFUNCTION+ , pattern LUA_TUSERDATA+ , pattern LUA_TTHREAD+ -- ** Relational operator codes+ , OPCode (..)+ , pattern LUA_OPEQ+ , pattern LUA_OPLT+ , pattern LUA_OPLE+ , StatusCode (..)+ -- ** Status codes+ , pattern LUA_OK+ , pattern LUA_YIELD+ , pattern LUA_ERRRUN+ , pattern LUA_ERRSYNTAX+ , pattern LUA_ERRMEM+ , pattern LUA_ERRGCMM+ , pattern LUA_ERRERR+ , pattern LUA_ERRFILE++ -- * Stack index helpers+ , nthTop+ , nthBottom+ , nth+ , top+ -- * Functions+ , -- ** State manipulation+ lua_close+ , lua_newthread+ -- ** Basic stack manipulation+ , lua_absindex+ , lua_gettop+ , lua_settop+ , lua_pushvalue+ , lua_pop+ , lua_copy+ , lua_remove+ , lua_insert+ , lua_replace+ , lua_checkstack+ -- ** Access functions (stack → Haskell)+ , lua_isnil+ , lua_isboolean+ , lua_isnumber+ , lua_isinteger+ , lua_isstring+ , lua_isfunction+ , lua_istable+ , lua_iscfunction+ , lua_isuserdata+ , lua_islightuserdata+ , lua_isthread+ , lua_isnone+ , lua_isnoneornil+ , lua_type+ , lua_typename+ , lua_rawequal+ , lua_toboolean+ , lua_tocfunction+ , lua_tointegerx+ , lua_tonumberx+ , lua_tolstring+ , lua_topointer+ , lua_tothread+ , lua_touserdata+ , lua_rawlen+ -- ** Push functions (Haskell → stack)+ , lua_pushnil+ , lua_pushnumber+ , lua_pushinteger+ , lua_pushlstring+ , lua_pushstring+ , lua_pushcclosure+ , lua_pushboolean+ , lua_pushlightuserdata+ , lua_pushthread+ -- ** Get functions (Lua → stack)+ , lua_rawget+ , lua_rawgeti+ , lua_createtable+ , lua_newuserdata+ , lua_getmetatable+ , lua_getuservalue+ , lua_getglobal+ , lua_gettable+ -- ** Set functions (stack → Lua)+ , lua_rawset+ , lua_rawseti+ , lua_setmetatable+ , lua_setuservalue+ , lua_setglobal+ , lua_settable+ -- ** Misc (unsafe)+ , lua_concat+ , lua_next+ -- ** Load and run Lua code+ , lua_pcall+ , lua_load+ -- ** Coroutine functions+ , lua_status+ -- ** Garbage-collection+ , lua_gc+ , GCCode (..)+ , pattern LUA_GCSTOP+ , pattern LUA_GCRESTART+ , pattern LUA_GCCOLLECT+ , pattern LUA_GCCOUNT+ , pattern LUA_GCCOUNTB+ , pattern LUA_GCSTEP+ , pattern LUA_GCSETPAUSE+ , pattern LUA_GCSETSTEPMUL+ , pattern LUA_GCISRUNNING+ -- ** Miscellaneous functions+ , lua_pushglobaltable++ -- * The Auxiliary Library+ , luaL_getmetafield+ , luaL_getmetatable+ , luaL_loadbuffer+ , luaL_openlibs+ , luaL_newmetatable+ , luaL_ref+ , luaL_testudata+ , luaL_traceback+ , luaL_unref+ -- ** Registry fields+ , loadedTableRegistryField+ , preloadTableRegistryField+ -- ** References+ , Reference (..)+ , pattern LUA_REFNIL+ , pattern LUA_NOREF+ , fromReference+ , toReference++ -- * Ersatz functions+ , hsluaL_newstate+ , hsluaL_tolstring+ -- ** Get functions (Lua → stack)+ , hslua_gettable+ , hslua_getglobal+ -- ** Set functions (stack → Lua)+ , hslua_settable+ , hslua_setglobal+ -- ** Misc+ , hslua_error+ , hslua_next+ , hslua_concat+ , hslua_compare++ -- * Standard Lua libraries+ , luaopen_base+ , luaopen_table+ , luaopen_io+ , luaopen_os+ , luaopen_string+ , luaopen_math+ , luaopen_debug+ , luaopen_package++ -- * Push Haskell functions+ , hslua_pushhsfunction+ ) where++import Foreign.C (CInt)+import Lua.Auxiliary+import Lua.Call+import Lua.Constants+import Lua.Ersatz.Functions+import Lua.Ersatz.Auxiliary+import Lua.Lib+import Lua.Primary+import Lua.Types as Lua++-- | Runs operations on a new Lua @'Lua.State'@. The state is created+-- when the function is called and closed on return. The state, and all+-- pointers to values within it, __must not__ be used after the function+-- returns.+--+-- === Example+-- Run a small Lua operation (prints the major version of Lua).+--+-- > withNewState $ \l -> do+-- > luaL_openlibs l+-- > withCString "print" (lua_getglobal l)+-- > withCString "_VERSION" (lua_getglobal l)+-- > lua_pcall l (NumArgs 1) (NumResults 1) (StackIndex 0)+--+-- @since 2.0.0+withNewState :: (State -> IO a) -> IO a+withNewState f = do+ l <- hsluaL_newstate+ result <- f l+ lua_close l+ return result++--+-- Stack index helpers+--++-- | Stack index of the nth element from the top of the stack.+--+-- @since 2.0.0+nthTop :: CInt -> StackIndex+nthTop n = StackIndex (-n)+{-# INLINABLE nthTop #-}++-- | Stack index of the nth element from the bottom of the stack.+--+-- @since 2.0.0+nthBottom :: CInt -> StackIndex+nthBottom = StackIndex+{-# INLINABLE nthBottom #-}++-- | Alias for 'nthTop'.+--+-- @since 2.0.0+nth :: CInt -> StackIndex+nth = nthTop+{-# INLINABLE nth #-}++-- | Index of the topmost stack element.+--+-- @since 2.0.0+top :: StackIndex+top = nthTop 1+{-# INLINABLE top #-}
+ src/Lua/Auxiliary.hs view
@@ -0,0 +1,234 @@+{-# LANGUAGE CPP #-}+{-|+Module : Lua.Auxiliary+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : non-portable (depends on GHC)++Raw bindings to functions and constants of the auxiliary library.+-}+module Lua.Auxiliary+ ( -- * The Auxiliary Library+ luaL_getmetafield+ , luaL_getmetatable+ , luaL_loadbuffer+ , luaL_loadfile+ , luaL_loadfilex+ , luaL_openlibs+ , luaL_newmetatable+ , luaL_ref+ , luaL_testudata+ , luaL_traceback+ , luaL_unref+ , luaL_where+ -- ** Registry fields+ , loadedTableRegistryField+ , preloadTableRegistryField+ -- ** References+ , Reference (..)+ , fromReference+ , toReference+ ) where++import Foreign.C (CChar, CInt (CInt), CSize (CSize), CString)+import Lua.Types as Lua+import Foreign.Ptr++#ifndef HARDCODE_REG_KEYS+import System.IO.Unsafe (unsafePerformIO)+import qualified Foreign.C as C+#endif++#ifdef ALLOW_UNSAFE_GC+#define SAFTY unsafe+#else+#define SAFTY safe+#endif++-- * The Auxiliary Library++-- | Key, in the registry, for table of loaded modules.+loadedTableRegistryField :: String+#ifdef HARDCODE_REG_KEYS+loadedTableRegistryField = "_LOADED"+#else+loadedTableRegistryField = unsafePerformIO (C.peekCString c_loaded_table)+{-# NOINLINE loadedTableRegistryField #-}++foreign import capi unsafe "lauxlib.h value LUA_LOADED_TABLE"+ c_loaded_table :: CString+#endif++-- | Key, in the registry, for table of preloaded loaders.+preloadTableRegistryField :: String+#ifdef HARDCODE_REG_KEYS+preloadTableRegistryField = "_PRELOAD"+#else+preloadTableRegistryField = unsafePerformIO (C.peekCString c_preload_table)+{-# NOINLINE preloadTableRegistryField #-}++foreign import capi unsafe "lauxlib.h value LUA_PRELOAD_TABLE"+ c_preload_table :: CString+#endif++-- | Pushes onto the stack the field @e@ from the metatable of the+-- object at index @obj@ and returns the type of the pushed value. If+-- the object does not have a metatable, or if the metatable does not+-- have this field, pushes nothing and returns+-- @'Lua.Constants.LUA_TNIL'@.+foreign import capi SAFTY "lauxlib.h luaL_getmetafield"+ luaL_getmetafield :: Lua.State+ -> StackIndex -- ^ obj+ -> CString -- ^ e+ -> IO TypeCode++-- | Pushes onto the stack the metatable associated with name tname in+-- the registry (see @'luaL_newmetatable'@) (__nil__ if there is no+-- metatable associated with that name). Returns the type of the pushed+-- value.+foreign import capi SAFTY "lauxlib.h luaL_getmetatable"+ luaL_getmetatable :: Lua.State -> CString -> IO Lua.TypeCode++-- | Loads a buffer as a Lua chunk. This function uses @lua_load@ to+-- load the chunk in the buffer pointed to by @buff@ with size @sz@.+--+-- This function returns the same results as @lua_load@. @name@ is the+-- chunk name, used for debug information and error messages.+foreign import capi SAFTY "lauxlib.h luaL_loadbuffer"+ luaL_loadbuffer :: Lua.State+ -> Ptr CChar -- ^ buff+ -> CSize -- ^ sz+ -> CString -- ^ name+ -> IO Lua.StatusCode++-- | Equivalent to luaL_loadfilex with mode equal to @NULL@.+foreign import capi SAFTY "lauxlib.h luaL_loadfile"+ luaL_loadfile :: Lua.State+ -> Ptr CChar -- ^ filename+ -> IO Lua.StatusCode++-- | Loads a file as a Lua chunk. This function uses @lua_load@ to load+-- the chunk in the file named filename. If filename is @NULL@, then it+-- loads from the standard input. The first line in the file is ignored+-- if it starts with a @#@.+--+-- The string mode works as in function @lua_load@.+--+-- This function returns the same results as @lua_load@, but it has an+-- extra error code LUA_ERRFILE for file-related errors (e.g., it cannot+-- open or read the file).+--+-- As @lua_load@, this function only loads the chunk; it does not run+-- it.+foreign import capi SAFTY "lauxlib.h luaL_loadfilex"+ luaL_loadfilex :: Lua.State+ -> Ptr CChar -- ^ filename+ -> Ptr CChar -- ^ mode+ -> IO Lua.StatusCode++-- | If the registry already has the key @tname@, returns @0@.+-- Otherwise, creates a new table to be used as a metatable for+-- userdata, adds to this new table the pair @__name = tname@, adds to+-- the registry the pair @[tname] = new table@, and returns @1@. (The+-- entry @__name@ is used by some error-reporting functions.)+--+-- In both cases pushes onto the stack the final value associated with+-- @tname@ in the registry.+foreign import ccall SAFTY "lauxlib.h luaL_newmetatable"+ luaL_newmetatable :: Lua.State -> CString {- ^ tname -} -> IO Lua.LuaBool++-- | Opens all standard Lua libraries into the given state.+--+-- <https://www.lua.org/manual/5.3/manual.html#luaL_openlibs>+foreign import ccall unsafe "lualib.h luaL_openlibs"+ luaL_openlibs :: Lua.State -> IO ()++-- | Creates and returns a reference, in the table at index @t@, for the+-- object at the top of the stack (and pops the object).+--+-- A reference is a unique integer key. As long as you do not manually+-- add integer keys into table @t@, @luaL_ref@ ensures the uniqueness of+-- the key it returns. You can retrieve an object referred by reference+-- @r@ by calling @lua_rawgeti l t r@. Function @'luaL_unref'@ frees a+-- reference and its associated object.+--+-- If the object at the top of the stack is nil, @luaL_ref@ returns the+-- constant @'Lua.Constants.LUA_REFNIL'@. The constant+-- @'Lua.Constants.LUA_NOREF'@ is guaranteed to be different+-- from any reference returned by @luaL_ref@.+foreign import ccall SAFTY "lauxlib.h luaL_ref"+ luaL_ref :: Lua.State -> StackIndex {- ^ t -} -> IO CInt++-- | Creates and pushes a traceback of the stack @l1@. If @msg@ is not+-- @NULL@ it is appended at the beginning of the traceback. The level+-- parameter tells at which level to start the traceback.+foreign import capi SAFTY "lauxlib.h luaL_traceback"+ luaL_traceback :: Lua.State -- ^ l+ -> Lua.State -- ^ l1+ -> CString -- ^ msg+ -> CInt -- ^ level+ -> IO ()++-- | Releases reference @ref@ from the table at index @t@ (see+-- @'luaL_ref'@). The entry is removed from the table, so that the+-- referred object can be collected. The reference @ref@ is also freed+-- to be used again.+foreign import ccall SAFTY "lauxlib.h luaL_unref"+ luaL_unref :: Lua.State -> StackIndex {- ^ t -} -> CInt {- ^ ref -} -> IO ()++-- | Checks whether the function argument @arg@ is a userdata of the+-- type @tname@ (see @'luaL_newmetatable'@) and returns the userdata+-- address (see @'Lua.lua_touserdata'@). Returns @NULL@ if the+-- test fails.+--+-- <https://www.lua.org/manual/5.3/manual.html#luaL_testudata>+foreign import capi SAFTY "lauxlib.h luaL_testudata"+ luaL_testudata :: Lua.State -- ^ l+ -> StackIndex -- ^ arg+ -> CString -- ^ tname+ -> IO (Ptr ())++-- | Pushes onto the stack a string identifying the current position of+-- the control at level @lvl@ in the call stack. Typically this string+-- has the following format:+--+-- > chunkname:currentline:+--+-- Level 0 is the running function, level 1 is the function that called+-- the running function, etc.+--+-- This function is used to build a prefix for error messages.+foreign import capi SAFTY "lauxlib.h luaL_where"+ luaL_where :: Lua.State -- ^ l+ -> CInt -- ^ lvl+ -> IO ()++--+-- References+--++-- | Reference to a stored value.+data Reference =+ Reference CInt -- ^ Reference to a stored value+ | RefNil -- ^ Reference to a nil value+ deriving (Eq, Show)++foreign import capi SAFTY "lauxlib.h value LUA_REFNIL"+ refnil :: CInt++-- | Convert a reference to its C representation.+fromReference :: Reference -> CInt+fromReference = \case+ Reference x -> x+ RefNil -> refnil++-- | Create a reference from its C representation.+toReference :: CInt -> Reference+toReference x =+ if x == refnil+ then RefNil+ else Reference x
+ src/Lua/Call.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE CPP #-}+{-|+Module : Lua.Call+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : non-portable (depends on GHC)++Function to push Haskell functions as Lua C functions.++Haskell functions are converted into C functions in a two-step process.+First, a function pointer to the Haskell function is stored in a Lua+userdata object. The userdata gets a metatable which allows to invoke+the object as a function. The userdata also ensures that the function+pointer is freed when the object is garbage collected in Lua.++In a second step, the userdata is then wrapped into a C closure. The+wrapping function calls the userdata object and implements the error+protocol, converting special error values into proper Lua errors.+-}+module Lua.Call+ ( hslua_pushhsfunction+ ) where++import Foreign.C (CInt (CInt))+import Foreign.Ptr (Ptr, castPtr, nullPtr)+import Foreign.StablePtr (StablePtr, deRefStablePtr, newStablePtr)+import Foreign.Storable (peek)+import Lua.Types+ ( NumResults (NumResults)+ , PreCFunction+ , State (State)+ )++#ifdef ALLOW_UNSAFE_GC+#define SAFTY unsafe+#else+#define SAFTY safe+#endif++-- | Retrieve the pointer to a Haskell function from the wrapping+-- userdata object.+foreign import ccall SAFTY "hslcall.c hslua_extracthsfun"+ hslua_extracthsfun :: State -> IO (Ptr ())++-- | Creates a new C function created from a 'PreCFunction'. The+-- function pointer to the PreCFunction is stored in a userdata object,+-- which is then wrapped by a C closure. The userdata object ensures+-- that the function pointer is freed when the function is garbage+-- collected in Lua.+foreign import ccall SAFTY "hslcall.c hslua_newhsfunction"+ hslua_newhsfunction :: State -> StablePtr a -> IO ()++-- | Pushes a Haskell operation as a Lua function. The Haskell operation+-- is expected to follow the custom error protocol, i.e., it must signal+-- errors with @'Lua.hslua_error'@.+--+-- === Example+-- Export the function to calculate triangular numbers.+--+-- > let triangular :: PreCFunction+-- > triangular l' = do+-- > n <- lua_tointegerx l' (nthBottom 1) nullPtr+-- > lua_pushinteger l' (sum [1..n])+-- > return (NumResults 1)+-- >+-- > hslua_newhsfunction l triangular+-- > withCString "triangular" (lua_setglobal l)+--+hslua_pushhsfunction :: State -> PreCFunction -> IO ()+hslua_pushhsfunction l preCFn =+ newStablePtr preCFn >>= hslua_newhsfunction l+{-# INLINABLE hslua_pushhsfunction #-}++-- | Call the Haskell function stored in the userdata. This+-- function is exported as a C function, as the C code uses it as+-- the @__call@ value of the wrapping userdata metatable.+hslua_callhsfun :: PreCFunction+hslua_callhsfun l = do+ udPtr <- hslua_extracthsfun l+ if udPtr == nullPtr+ then error "Cannot call function; corrupted Lua object!"+ else do+ fn <- peek (castPtr udPtr) >>= deRefStablePtr+ fn l++foreign export ccall hslua_callhsfun :: PreCFunction
+ src/Lua/Constants.hsc view
@@ -0,0 +1,243 @@+{-# LANGUAGE PatternSynonyms #-}+{-|+Module : Lua.Constants+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : ForeignFunctionInterface++Lua constants+-}+module Lua.Constants+ ( -- * Special values+ pattern LUA_MULTRET+ -- * Pseudo-indices+ , pattern LUA_REGISTRYINDEX+ -- * Basic types+ , pattern LUA_TNONE+ , pattern LUA_TNIL+ , pattern LUA_TBOOLEAN+ , pattern LUA_TLIGHTUSERDATA+ , pattern LUA_TNUMBER+ , pattern LUA_TSTRING+ , pattern LUA_TTABLE+ , pattern LUA_TFUNCTION+ , pattern LUA_TUSERDATA+ , pattern LUA_TTHREAD+ -- * Status codes+ , pattern LUA_OK+ , pattern LUA_YIELD+ , pattern LUA_ERRRUN+ , pattern LUA_ERRSYNTAX+ , pattern LUA_ERRMEM+ , pattern LUA_ERRGCMM+ , pattern LUA_ERRERR+ , pattern LUA_ERRFILE+ -- * Relational operator codes+ , pattern LUA_OPEQ+ , pattern LUA_OPLT+ , pattern LUA_OPLE+ -- * Garbage-collection options+ , pattern LUA_GCSTOP+ , pattern LUA_GCRESTART+ , pattern LUA_GCCOLLECT+ , pattern LUA_GCCOUNT+ , pattern LUA_GCCOUNTB+ , pattern LUA_GCSTEP+ , pattern LUA_GCSETPAUSE+ , pattern LUA_GCSETSTEPMUL+ , pattern LUA_GCISRUNNING+ -- * Predefined references+ , pattern LUA_REFNIL+ , pattern LUA_NOREF+ -- * Boolean+ , pattern TRUE+ , pattern FALSE+ ) where++import Foreign.C (CInt (..))+import Lua.Types++#include <lua.h>+#include <lauxlib.h>++--+-- Special values+--++-- | Option for multiple returns in @'Lua.lua_pcall'@.+pattern LUA_MULTRET :: NumResults+pattern LUA_MULTRET = NumResults (#{const LUA_MULTRET})++-- | Stack index of the Lua registry.+pattern LUA_REGISTRYINDEX :: StackIndex+pattern LUA_REGISTRYINDEX = StackIndex (#{const LUA_REGISTRYINDEX})++--+-- Type of Lua values+--+-- | Non-valid stack index+pattern LUA_TNONE :: TypeCode+pattern LUA_TNONE = TypeCode (#{const LUA_TNONE})++-- | Type of Lua's @nil@ value+pattern LUA_TNIL :: TypeCode+pattern LUA_TNIL = TypeCode (#{const LUA_TNIL})++-- | Type of Lua booleans+pattern LUA_TBOOLEAN :: TypeCode+pattern LUA_TBOOLEAN = TypeCode (#{const LUA_TBOOLEAN})++-- | Type of light userdata+pattern LUA_TLIGHTUSERDATA :: TypeCode+pattern LUA_TLIGHTUSERDATA = TypeCode (#{const LUA_TLIGHTUSERDATA})++-- | Type of Lua numbers. See @'Lua.Number'@+pattern LUA_TNUMBER :: TypeCode+pattern LUA_TNUMBER = TypeCode (#{const LUA_TNUMBER})++-- | Type of Lua string values+pattern LUA_TSTRING :: TypeCode+pattern LUA_TSTRING = TypeCode (#{const LUA_TSTRING})++-- | Type of Lua tables+pattern LUA_TTABLE :: TypeCode+pattern LUA_TTABLE = TypeCode (#{const LUA_TTABLE})++-- | Type of functions, either normal or @'CFunction'@+pattern LUA_TFUNCTION :: TypeCode+pattern LUA_TFUNCTION = TypeCode (#{const LUA_TFUNCTION})++-- | Type of full user data+pattern LUA_TUSERDATA :: TypeCode+pattern LUA_TUSERDATA = TypeCode (#{const LUA_TUSERDATA})++-- | Type of Lua threads+pattern LUA_TTHREAD :: TypeCode+pattern LUA_TTHREAD = TypeCode (#{const LUA_TTHREAD})++--+-- Status codes+--++-- | Success.+pattern LUA_OK :: StatusCode+pattern LUA_OK = StatusCode #{const LUA_OK}++-- | Yielding / suspended coroutine.+pattern LUA_YIELD :: StatusCode+pattern LUA_YIELD = StatusCode #{const LUA_YIELD}++-- | A runtime error.+pattern LUA_ERRRUN :: StatusCode+pattern LUA_ERRRUN = StatusCode #{const LUA_ERRRUN}++-- | A syntax error.+pattern LUA_ERRSYNTAX :: StatusCode+pattern LUA_ERRSYNTAX = StatusCode #{const LUA_ERRSYNTAX}++-- | Memory allocation error. For such errors, Lua does not call the+-- message handler.+pattern LUA_ERRMEM :: StatusCode+pattern LUA_ERRMEM = StatusCode #{const LUA_ERRMEM}++-- | Error while running a @__gc@ metamethod. For such errors, Lua does+-- not call the message handler (as this kind of error typically has no+-- relation with the function being called).+pattern LUA_ERRGCMM :: StatusCode+pattern LUA_ERRGCMM = StatusCode #{const LUA_ERRGCMM}++-- | Error while running the message handler.+pattern LUA_ERRERR :: StatusCode+pattern LUA_ERRERR = StatusCode #{const LUA_ERRERR}++-- | File related error (e.g., the file cannot be opened or read).+pattern LUA_ERRFILE :: StatusCode+pattern LUA_ERRFILE = StatusCode #{const LUA_ERRFILE}++--+-- Comparison operators+--++-- | Compares for equality (==)+pattern LUA_OPEQ :: OPCode+pattern LUA_OPEQ = OPCode #{const LUA_OPEQ}++-- | Compares for less than (<)+pattern LUA_OPLT :: OPCode+pattern LUA_OPLT = OPCode #{const LUA_OPLT}++-- | Compares for less or equal (<=)+pattern LUA_OPLE :: OPCode+pattern LUA_OPLE = OPCode #{const LUA_OPLE}++--+-- Garbage-collection options+--++-- | Stops the garbage collector.+pattern LUA_GCSTOP :: GCCode+pattern LUA_GCSTOP = GCCode #{const LUA_GCSTOP}++-- | Restarts the garbage collector.+pattern LUA_GCRESTART :: GCCode+pattern LUA_GCRESTART = GCCode #{const LUA_GCRESTART}++-- | Performs a full garbage-collection cycle.+pattern LUA_GCCOLLECT :: GCCode+pattern LUA_GCCOLLECT = GCCode #{const LUA_GCCOLLECT}++-- | Returns the current amount of memory (in Kbytes) in use by Lua.+pattern LUA_GCCOUNT :: GCCode+pattern LUA_GCCOUNT = GCCode #{const LUA_GCCOUNT}++-- | Returns the remainder of dividing the current amount of bytes of+-- memory in use by Lua by 1024.+pattern LUA_GCCOUNTB :: GCCode+pattern LUA_GCCOUNTB = GCCode #{const LUA_GCCOUNTB}++-- | Performs an incremental step of garbage collection.+pattern LUA_GCSTEP :: GCCode+pattern LUA_GCSTEP = GCCode #{const LUA_GCSTEP}++-- | Sets data as the new value for the pause of the collector (see+-- §2.5) and returns the previous value of the pause.+pattern LUA_GCSETPAUSE :: GCCode+pattern LUA_GCSETPAUSE = GCCode #{const LUA_GCSETPAUSE}++-- | Sets data as the new value for the step multiplier of the collector+-- (see §2.5) and returns the previous value of the step multiplier.+pattern LUA_GCSETSTEPMUL :: GCCode+pattern LUA_GCSETSTEPMUL = GCCode #{const LUA_GCSETSTEPMUL}++-- | Returns a boolean that tells whether the collector is running+-- (i.e., not stopped).+pattern LUA_GCISRUNNING :: GCCode+pattern LUA_GCISRUNNING = GCCode #{const LUA_GCISRUNNING}++--+-- Special registry values+--++-- | Value signaling that no reference was created.+pattern LUA_REFNIL :: CInt+pattern LUA_REFNIL = #{const LUA_NOREF}++-- | Value signaling that no reference was found.+pattern LUA_NOREF :: CInt+pattern LUA_NOREF = #{const LUA_NOREF}++--+-- Booleans+--++-- | Value which Lua usually uses as 'True'.+pattern TRUE :: LuaBool+pattern TRUE = LuaBool 1++-- | Value which Lua usually uses as 'False'.+pattern FALSE :: LuaBool+pattern FALSE = LuaBool 0
+ src/Lua/Ersatz.hs view
@@ -0,0 +1,31 @@+{-|+Module : Lua.Ersatz+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta++Ersatz functions for Lua API items which may, directly or indirectly,+throw a Lua error.+-}+module Lua.Ersatz+ ( -- * Get functions (Lua -> stack)+ hslua_gettable+ , hslua_getglobal+ -- * Set functions (stack -> Lua)+ , hslua_settable+ , hslua_setglobal+ -- * Misc+ , hslua_error+ , hslua_next+ , hslua_concat+ , hslua_compare+ -- * Auxiliary Library+ , hsluaL_newstate+ , hsluaL_tolstring+ )where++import Lua.Ersatz.Functions+import Lua.Ersatz.Auxiliary (hsluaL_newstate, hsluaL_tolstring)
+ src/Lua/Ersatz/Auxiliary.hs view
@@ -0,0 +1,32 @@+{-|+Module : Lua.Ersatz.Auxiliary+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : non-portable (depends on GHC)++Raw bindings to ersatz functions of the auxiliary library.+-}+module Lua.Ersatz.Auxiliary+ ( -- * Auxiliary Library+ hsluaL_newstate+ , hsluaL_tolstring+ ) where++import Foreign.C (CChar, CInt (CInt), CSize)+import Lua.Types (StackIndex)+import Foreign.Ptr (Ptr)+import qualified Lua.Types as Lua++-- | Creates a new Lua state and set extra registry values for error+-- bookkeeping.+foreign import ccall unsafe "hslauxlib.h hsluaL_newstate"+ hsluaL_newstate :: IO Lua.State++-- | Converts object to string, respecting any metamethods; returns+-- @NULL@ if an error occurs.+foreign import ccall safe "hslauxlib.h hsluaL_tolstring"+ hsluaL_tolstring :: Lua.State -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
+ src/Lua/Ersatz/Functions.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE CPP #-}+{-|+Module : Lua.Ersatz.Functions+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : ForeignFunctionInterface, CPP++Ersatz functions for Lua API items which may, directly or indirectly,+throw a Lua error.+-}+module Lua.Ersatz.Functions+ ( hslua_compare+ -- * Get functions (Lua -> stack)+ , hslua_gettable+ , hslua_getglobal+ -- * Set functions (stack -> Lua)+ , hslua_settable+ , hslua_setglobal+ -- * Misc+ , hslua_error+ , hslua_next+ , hslua_concat+ )where++import Foreign.C+import Lua.Types as Lua+import Foreign.Ptr++#ifdef ALLOW_UNSAFE_GC+#define SAFTY unsafe+#else+#define SAFTY safe+#endif++-- | Compares two Lua values. Returns @1@ if the value at index @index1@+-- satisfies op when compared with the value at index @index2@,+-- following the semantics of the corresponding Lua operator (that is,+-- it may call metamethods). Otherwise returns @0@. Also returns @0@ if+-- any of the indices is not valid.+--+-- The value of op must be one of the following constants:+--+-- - 'Lua.Constants.LUA_OPEQ': compares for equality (==)+-- - 'Lua.Constants.LUA_OPLT': compares for less than (<)+-- - 'Lua.Constants.LUA_OPLE': compares for less or equal (<=)+--+-- This function wraps @lua_compare@ and takes an additional parameter+-- @status@; if it is not @NULL@, then the return value is set to the+-- status after calling @lua_compare@.+foreign import capi safe "hslua.h hslua_compare"+ hslua_compare :: Lua.State+ -> StackIndex -- ^ index 1+ -> StackIndex -- ^ index 2+ -> OPCode -- ^ operator+ -> Ptr StatusCode -- ^ status+ -> IO LuaBool++--+-- Get functions (Lua -> stack)+--++-- | Behaves like @'Lua.Functions.lua_gettable'@, but prevents+-- unrecoverable program crashes by calling that function through+-- @'Lua.lua_pcall'@. Takes an additional status code pointer+-- that is set to the status returned by @lua_pcall@.+foreign import ccall safe "hslua.h hslua_gettable"+ hslua_gettable :: Lua.State -> StackIndex -> Ptr StatusCode -> IO TypeCode++-- | Behaves like @'Lua.Functions.lua_getglobal'@, but prevents+-- unrecoverable program crashes by calling that function through+-- @'Lua.lua_pcall'@. Takes an additional status code pointer+-- that is set to the status returned by @lua_pcall@.+foreign import ccall safe "hslua.h hslua_getglobal"+ hslua_getglobal :: Lua.State+ -> CString+ -> CSize+ -> Ptr StatusCode+ -> IO TypeCode++--+-- Set functions (stack -> Lua)+--++-- | Behaves like @'Lua.Functions.lua_settable'@, but prevents+-- unrecoverable program crashes by calling that function through+-- @'Lua.lua_pcall'@. Takes an additional status code pointer+-- that is set to the status returned by @lua_pcall@.+foreign import ccall safe "hslua.h hslua_settable"+ hslua_settable :: Lua.State -> StackIndex -> Ptr StatusCode -> IO ()++-- | Behaves like @'Lua.Functions.lua_setglobal'@, but prevents+-- unrecoverable program crashes by calling that function through+-- @'Lua.lua_pcall'@. Takes an additional status code pointer+-- that is set to the status returned by @lua_pcall@.+foreign import ccall safe "hslua.h hslua_setglobal"+ hslua_setglobal :: Lua.State -> CString -> CSize -> Ptr StatusCode -> IO ()++--+-- Miscellaneous functions+--++-- | Replacement for+-- <https://lua.org/manual/5.3/manual.html#lua_error lua_error>; it uses+-- the HsLua error signaling convention instead of raw Lua errors.+foreign import ccall SAFTY "hslua.h hslua_error"+ hslua_error :: Lua.State -> IO NumResults++-- | Wrapper around+-- <https://lua.org/manual/5.3/manual.html#lua_next lua_next> which+-- catches any Lua errors.+foreign import ccall safe "hslua.h hslua_next"+ hslua_next :: Lua.State -> StackIndex -> Ptr StatusCode -> IO LuaBool++-- | Wrapper around+-- <https://lua.org/manual/5.3/manual.html#lua_concat lua_concat>+-- which catches any Lua errors.+foreign import ccall safe "hslua.h hslua_concat"+ hslua_concat :: Lua.State -> NumArgs -> Ptr StatusCode -> IO ()
+ src/Lua/Lib.hs view
@@ -0,0 +1,59 @@+{-|+Module : Lua.Lib+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : ForeignFunctionInterface, CPP++Lua standard libraries.+-}+module Lua.Lib+ ( luaopen_base+ , luaopen_table+ , luaopen_io+ , luaopen_os+ , luaopen_string+ , luaopen_math+ , luaopen_debug+ , luaopen_package+ )+where++import Lua.Types (CFunction)++-- * Lua Libraries++-- | Pointer to function opening the base library.+foreign import ccall unsafe "lualib.h &luaopen_base"+ luaopen_base :: CFunction++-- | Pointer to function opening the table library.+foreign import ccall unsafe "lualib.h &luaopen_table"+ luaopen_table :: CFunction++-- | Pointer to function opening the io library.+foreign import ccall unsafe "lualib.h &luaopen_io"+ luaopen_io :: CFunction++-- | Pointer to function opening the os library.+foreign import ccall unsafe "lualib.h &luaopen_os"+ luaopen_os :: CFunction++-- | Pointer to function opening the string library.+foreign import ccall unsafe "lualib.h &luaopen_string"+ luaopen_string :: CFunction++-- | Pointer to function opening the math library.+foreign import ccall unsafe "lualib.h &luaopen_math"+ luaopen_math :: CFunction++-- | Pointer to function opening the debug library.+foreign import ccall unsafe "lualib.h &luaopen_debug"+ luaopen_debug :: CFunction++-- | Pointer to function opening the package library.+foreign import ccall unsafe "lualib.h &luaopen_package"+ luaopen_package :: CFunction
+ src/Lua/Primary.hs view
@@ -0,0 +1,896 @@+{-# LANGUAGE CPP #-}+{-|+Module : Lua.Primary+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : ForeignFunctionInterface, CPP++Haskell bindings to Lua C API functions.++The exposed functions correspond closely to the respective C Lua API+functions. However, C API functions which can throw Lua errors are not+exported directly, as any errors would crash the program. Non-error+throwing @hslua_@ versions are provided instead. The @hslua@ ersatz+functions have worse performance than the original.++Some of the Lua functions may, directly or indirectly, call a Haskell+function, and trigger garbage collection, rescheduling etc. These+functions are always imported safely (i.e., with the @safe@ keyword).++However, all function can trigger garbage collection. If that can lead+to problems, then the package should be configured without flag+@allow-unsafe-gc@.+-}+module Lua.Primary+ ( lua_absindex+ , lua_checkstack+ , lua_close+ , lua_concat+ , lua_copy+ , lua_createtable+ , lua_gc+ , lua_getglobal+ , lua_getmetatable+ , lua_gettable+ , lua_gettop+ , lua_getuservalue+ , lua_insert+ , lua_isboolean+ , lua_iscfunction+ , lua_isfunction+ , lua_isinteger+ , lua_islightuserdata+ , lua_isnil+ , lua_isnone+ , lua_isnoneornil+ , lua_isnumber+ , lua_isstring+ , lua_istable+ , lua_isthread+ , lua_isuserdata+ , lua_load+ , lua_newthread+ , lua_newuserdata+ , lua_next+ , lua_pcall+ , lua_pop+ , lua_pushboolean+ , lua_pushcclosure+ , lua_pushglobaltable+ , lua_pushinteger+ , lua_pushlightuserdata+ , lua_pushlstring+ , lua_pushnil+ , lua_pushnumber+ , lua_pushstring+ , lua_pushthread+ , lua_pushvalue+ , lua_rawequal+ , lua_rawget+ , lua_rawgeti+ , lua_rawlen+ , lua_rawset+ , lua_rawseti+ , lua_remove+ , lua_replace+ , lua_setglobal+ , lua_setmetatable+ , lua_settable+ , lua_settop+ , lua_setuservalue+ , lua_status+ , lua_toboolean+ , lua_tocfunction+ , lua_tointegerx+ , lua_tolstring+ , lua_tonumberx+ , lua_topointer+ , lua_tothread+ , lua_touserdata+ , lua_type+ , lua_typename+ , module Lua.Ersatz.Functions+ , module Lua.Ersatz.Auxiliary+ )+where++import Foreign.C+import Lua.Ersatz.Auxiliary+import Lua.Ersatz.Functions+import Lua.Types as Lua+import Foreign.Ptr++#ifdef ALLOW_UNSAFE_GC+#define SAFTY unsafe+#else+#define SAFTY safe+#endif++-- | Converts the acceptable index @idx@ into an equivalent absolute+-- index (that is, one that does not depend on the stack top).+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_absindex>+foreign import ccall unsafe "lua.h lua_absindex"+ lua_absindex :: Lua.State+ -> StackIndex -- ^ idx+ -> IO StackIndex++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_checkstack>+foreign import capi unsafe "lua.h lua_checkstack"+ lua_checkstack :: Lua.State -> CInt {- ^ n -} -> IO LuaBool++-- | 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. In 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_close>+foreign import ccall safe "lua.h lua_close"+ lua_close :: Lua.State -> IO ()++-- | 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).+--+-- __WARNING__: @lua_concat@ is unsafe in Haskell: This function will+-- cause an unrecoverable crash an error if any of the concatenated+-- values causes an error when executing a metamethod. Consider using+-- the @'Lua.hslua_concat'@ ersatz function instead.+foreign import ccall SAFTY "lua.h lua_concat"+ lua_concat :: State -> CInt {- ^ n -} -> IO ()+{-# WARNING lua_concat+ [ "This is an unsafe function, it will cause a program crash if"+ , "a metamethod throws an error."+ , "Consider using hslua_concat instead."+ ] #-}++-- | Copies the element at index @fromidx@ into the valid index @toidx@,+-- replacing the value at that position. Values at other positions are+-- not affected.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_copy>+foreign import ccall unsafe "lua.h lua_copy"+ lua_copy :: Lua.State+ -> StackIndex -- ^ fromidx+ -> StackIndex -- ^ toidx+ -> IO ()++-- | 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@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_createtable>.+foreign import ccall SAFTY "lua.h lua_createtable"+ lua_createtable :: Lua.State+ -> CInt -- ^ narr+ -> CInt -- ^ nrec+ -> IO ()++-- | Controls the garbage collector.+--+-- See the Lua docs at+-- <https://www.lua.org/manual/5.3/manual.html#lua_gc>.+foreign import ccall safe "lua.h lua_gc"+ lua_gc :: Lua.State -> GCCode {- ^ what -} -> CInt {- ^ data -} -> IO CInt++-- | Pushes onto the stack the value of the global name. Returns the+-- type of that value.+--+-- __WARNING__: @lua_getglobal@ is unsafe in Haskell: if the call to a+-- metamethod triggers an error, then that error cannot be handled and+-- will lead to an unrecoverable program crash. Consider using the+-- @'Lua.hslua_getglobal'@ ersatz function instead. Likewise, the+-- metamethod may not call a Haskell function unless the library was+-- compiled without @allow-unsafe-gc@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_getglobal>.+foreign import ccall SAFTY "lua.h lua_getglobal"+ lua_getglobal :: State -> CString {- ^ name -} -> IO TypeCode+{-# WARNING lua_getglobal+ [ "This is an unsafe function, errors will lead to a program crash;"+ , "consider using hslua_getglobal instead."+ ] #-}++-- | If the value at the given index has a metatable, the function+-- pushes that metatable onto the stack and returns @1@. Otherwise, the+-- function returns @0@ and pushes nothing on the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_getmetatable>.+foreign import ccall unsafe "lua.h lua_getmetatable"+ lua_getmetatable :: Lua.State -> StackIndex -> IO LuaBool++-- | 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>).+--+-- Returns the type of the pushed value.+--+-- __WARNING__: @lua_gettable@ is unsafe in Haskell: if the call to a+-- metamethod triggers an error, then that error cannot be handled and+-- will lead to an unrecoverable program crash. Consider using the+-- @'Lua.hslua_gettable'@ ersatz function instead. Likewise, the+-- metamethod may not call a Haskell function unless the library was+-- compiled without @allow-unsafe-gc@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_gettable>.+foreign import ccall SAFTY "lua.h lua_gettable"+ lua_gettable :: Lua.State -> StackIndex {- ^ index -} -> IO TypeCode+{-# WARNING lua_gettable+ [ "This is an unsafe function, errors will lead to a program crash;"+ , "consider using hslua_gettable instead."+ ] #-}++-- | 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).+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_gettop>+foreign import ccall unsafe "lua.h lua_gettop"+ lua_gettop :: Lua.State -> IO StackIndex++-- | Pushes onto the stack the Lua value associated with the full+-- userdata at the given index.+--+-- Returns the type of the pushed value.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_getuservalue>+foreign import ccall unsafe "lua.h lua_getuservalue"+ lua_getuservalue :: Lua.State -> StackIndex -> IO TypeCode++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_insert>+foreign import capi unsafe "lua.h lua_insert"+ lua_insert :: Lua.State -> StackIndex -> IO ()++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- boolean, and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isboolean>+foreign import capi unsafe "lua.h lua_isboolean"+ lua_isboolean :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a C+-- function, and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_iscfunction>+foreign import ccall unsafe "lua.h lua_iscfunction"+ lua_iscfunction :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- function (either C or Lua), and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isfunction>+foreign import capi unsafe "lua.h lua_isfunction"+ lua_isfunction :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.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 @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isinteger>+foreign import ccall unsafe "lua.h lua_isinteger"+ lua_isinteger :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- light userdata, and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_islightuserdata>+foreign import capi unsafe "lua.h lua_islightuserdata"+ lua_islightuserdata :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is+-- __nil__, and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isnil>+foreign import capi unsafe "lua.h lua_isnil"+ lua_isnil :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the given index is not valid, and+-- @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isnone>+foreign import capi unsafe "lua.h lua_isnone"+ lua_isnone :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the given index is not valid or if+-- the value at the given index is __nil__, and @'Lua.FALSE'@+-- otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isnoneornil>+foreign import capi unsafe "lua.h lua_isnoneornil"+ lua_isnoneornil :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- number or a string convertible to a number, and @'Lua.FALSE'@+-- otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isnumber>+foreign import ccall unsafe "lua.h lua_isnumber"+ lua_isnumber :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- string or a number (which is always convertible to a string), and+-- @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isstring>+foreign import ccall unsafe "lua.h lua_isstring"+ lua_isstring :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- table, and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_istable>+foreign import capi unsafe "lua.h lua_istable"+ lua_istable :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- thread, and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isthread>+foreign import capi unsafe "lua.h lua_isthread"+ lua_isthread :: Lua.State -> StackIndex -> IO LuaBool++-- | Returns @'Lua.TRUE'@ if the value at the given index is a+-- userdata (either full or light), and @'Lua.FALSE'@ otherwise.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_isuserdata>+foreign import ccall unsafe "lua.h lua_isuserdata"+ lua_isuserdata :: Lua.State -> StackIndex -> IO LuaBool++-- | Loads a Lua chunk (without running it). If there are no errors,+-- @lua_load@ pushes the compiled chunk as a Lua function on top of the+-- stack. Otherwise, it pushes an error message.+--+-- The return values of @lua_load@ are:+--+-- - @'Lua.LUA_OK'@: no errors;+-- - @'Lua.LUA_ERRSYNTAX'@: syntax error during pre-compilation;+-- - @'Lua.LUA_ERRMEM'@: memory allocation error;+-- - @'Lua.LUA_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.+--+-- @lua_load@ automatically detects whether the chunk is text or binary,+-- and loads it accordingly (see program luac).+--+-- The @lua_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>).+--+-- @lua_load@ automatically detects whether the chunk is text or binary+-- and loads it accordingly (see program @luac@). The string mode works+-- as in function @load@, with the addition that a @NULL@ value is+-- equivalent to the string "bt".+--+-- @lua_load@ uses the stack internally, so the reader function must+-- always leave the stack unmodified when returning.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_load>.+foreign import ccall safe "lua.h lua_load"+ lua_load :: Lua.State+ -> Lua.Reader -- ^ reader+ -> Ptr () -- ^ data+ -> CString -- ^ chunkname+ -> CString -- ^ mode+ -> IO StatusCode++-- | Creates a new thread, pushes it on the stack, and returns a+-- 'Lua.State' that represents this new thread. The new thread returned+-- by this function shares with the original thread its global+-- environment, but has an independent execution stack.+--+-- There is no explicit function to close or to destroy a thread.+-- Threads are subject to garbage collection, like any Lua object.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_newthread>+foreign import ccall SAFTY "lua.h lua_newthread"+ lua_newthread :: Lua.State -> IO Lua.State++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_newuserdata>.+foreign import ccall SAFTY "lua.h lua_newuserdata"+ lua_newuserdata :: Lua.State -> CSize -> IO (Ptr ())+++-- | 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+-- <https://www.lua.org/manual/5.3/manual.html#lua_next lua_next>+-- returns 'FALSE' (and pushes nothing).+--+-- A typical traversal looks like this:+--+-- > -- table is in the stack at index 't'+-- > lua_pushnil l -- first key+-- > let loop = lua_next l t >>= \case+-- > FALSE -> return ()+-- > _ -> do+-- > lua_type l (-2) >>= lua_typename l >>= peekCString >>= putStrLn+-- > lua_type l (-1) >>= lua_typename l >>= peekCString >>= putStrLn+-- > -- removes 'value'; keeps 'key' for next iteration+-- > lua_pop l 1+-- > loop+-- > loop+--+-- While traversing a table, do not call 'lua_tolstring' directly on a+-- key, unless you know that the key is actually a string. Recall that+-- 'lua_tolstring' may change the value at the given index; this+-- confuses the next call to+-- <https://www.lua.org/manual/5.3/manual.html#lua_next lua_next>.+--+-- See function+-- <https://www.lua.org/manual/5.3/manual.html#pdf-next next> for the+-- caveats of modifying the table during its traversal.+--+-- __WARNING__: @lua_next@ is unsafe in Haskell: This function will+-- cause an unrecoverable crash an error if the given key is neither+-- @nil@ nor present in the table. Consider using the @'Lua.hslua_next'@+-- ersatz function instead.+foreign import ccall SAFTY "lua.h lua_next"+ lua_next :: State -> StackIndex {- ^ index -} -> IO LuaBool+{-# WARNING lua_next+ [ "This is an unsafe function, it will cause a program crash if"+ , "the given key is neither nil nor present in the table."+ , "Consider using hslua_next instead."+ ] #-}++-- | Calls a function in protected mode.+--+-- 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 @lua_pcall@; @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 @'Lua.LUA_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.+--+-- If there is any error, @lua_pcall@ catches it, pushes a single value+-- on the stack (the error message), and returns the error code.+-- @lua_pcall@ always removes the function and its arguments from the+-- stack.+--+-- If @msgh@ is @0@, then the error object returned on the stack is+-- exactly the original error object. Otherwise, @msgh@ 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+-- @'lua_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 @'lua_pcall'@, since by then+-- the stack has unwound.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pcall>.+foreign import capi safe "lua.h lua_pcall"+ lua_pcall :: Lua.State+ -> NumArgs -- ^ nargs+ -> NumResults -- ^ nresults+ -> StackIndex -- ^ msgh+ -> IO StatusCode++-- | Pops @n@ elements from the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pop>+foreign import capi unsafe "lua.h lua_pop"+ lua_pop :: Lua.State -> CInt {- ^ n -} -> IO ()++-- | Pushes a boolean value with the given value onto the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushboolean>.+foreign import ccall unsafe "lua.h lua_pushboolean"+ lua_pushboolean :: Lua.State -> LuaBool -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushcclosure>.+foreign import ccall SAFTY "lua.h lua_pushcclosure"+ lua_pushcclosure :: Lua.State+ -> CFunction -- ^ fn+ -> NumArgs -- ^ n+ -> IO ()++-- | Pushes the global environment onto the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushglobaltable>+foreign import capi unsafe "lua.h lua_pushglobaltable"+ lua_pushglobaltable :: Lua.State -> IO ()++-- | Pushes an integer with with the given value onto the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushinteger>.+foreign import ccall unsafe "lua.h lua_pushinteger"+ lua_pushinteger :: Lua.State -> Lua.Integer -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushlightuserdata>.+foreign import ccall unsafe "lua.h lua_pushlightuserdata"+ lua_pushlightuserdata :: Lua.State -> Ptr a -> IO ()++-- | Pushes the string pointed to by @s@ with size @len@ 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. The string can contain any binary data, including embedded+-- zeros.+--+-- Returns a pointer to the internal copy of the string.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushlstring>.+foreign import ccall SAFTY "lua.h lua_pushlstring"+ lua_pushlstring :: Lua.State+ -> Ptr CChar -- ^ s+ -> CSize -- ^ len+ -> IO ()++-- | Pushes a nil value onto the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushnil>.+foreign import ccall unsafe "lua.h lua_pushnil"+ lua_pushnil :: Lua.State -> IO ()++-- | Pushes a float with the given value onto the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushnumber>.+foreign import ccall unsafe "lua.h lua_pushnumber"+ lua_pushnumber :: Lua.State -> Lua.Number -> IO ()+++-- | 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.+--+-- Returns a pointer to the internal copy of the string.+--+-- If s is NULL, pushes nil and returns NULL.+foreign import ccall unsafe "lua.h lua_pushstring"+ lua_pushstring :: Lua.State -> CString {- ^ s -} -> IO CString+++-- | Pushes the current thread onto the stack. Returns @1@ iff this+-- thread is the main thread of its state.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushthread>.+foreign import ccall unsafe "lua.h lua_pushthread"+ lua_pushthread :: Lua.State -> IO CInt++-- | Pushes a copy of the element at the given index onto the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_pushvalue>+foreign import ccall unsafe "lua.h lua_pushvalue"+ lua_pushvalue :: Lua.State -> StackIndex -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_rawequal>+foreign import ccall unsafe "lua.h lua_rawequal"+ lua_rawequal :: Lua.State+ -> StackIndex -- ^ idx1+ -> StackIndex -- ^ idx2+ -> IO LuaBool++-- | Similar to @'lua_gettable'@, but does a raw access (i.e., without+-- metamethods).+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_rawget>.+foreign import ccall unsafe "lua.h lua_rawget"+ lua_rawget :: Lua.State -> StackIndex -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_rawgeti>.+foreign import ccall unsafe "lua.h lua_rawgeti"+ lua_rawgeti :: Lua.State -> StackIndex -> Lua.Integer {- ^ n -} -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_rawlen>.+foreign import ccall unsafe "lua.h lua_rawlen"+ lua_rawlen :: Lua.State -> StackIndex -> IO CSize++-- | Similar to @'lua_settable'@, but does a raw assignment (i.e.,+-- without metamethods).+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_rawset>.+foreign import ccall SAFTY "lua.h lua_rawset"+ lua_rawset :: Lua.State -> StackIndex -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_rawseti>.+foreign import ccall SAFTY "lua.h lua_rawseti"+ lua_rawseti :: Lua.State -> StackIndex -> Lua.Integer -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_remove>+foreign import capi unsafe "lua.h lua_remove"+ lua_remove :: Lua.State -> StackIndex -> IO ()++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_replace>+foreign import capi unsafe "lua.h lua_replace"+ lua_replace :: Lua.State -> StackIndex -> IO ()++-- | Pops a value from the stack and sets it as the new value of global+-- @name@.+--+-- __WARNING__: @lua_setglobal@ is unsafe in Haskell: if the call to a+-- metamethod triggers an error, then that error cannot be handled and+-- will lead to an unrecoverable program crash. Consider using the+-- @'Lua.hslua_setglobal'@ ersatz function instead. Likewise,+-- the global metamethod may not call a Haskell function unless the+-- library was compiled without @allow-unsafe-gc@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_setglobal>.+foreign import ccall SAFTY "lua.h lua_setglobal"+ lua_setglobal :: State -> CString {- ^ name -} -> IO ()+{-# WARNING lua_setglobal+ [ "This is an unsafe function, errors will lead to a program crash;"+ , "consider using hslua_getglobal instead."+ ] #-}++-- | Pops a table from the stack and sets it as the new metatable for+-- the value at the given index.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_setmetatable>.+foreign import ccall unsafe "lua.h lua_setmetatable"+ lua_setmetatable :: Lua.State -> StackIndex -> IO ()++-- | 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>).+--+-- __WARNING__: @lua_settable@ is unsafe in Haskell: if the call to a+-- metamethod triggers an error, then that error cannot be handled and+-- will lead to an unrecoverable program crash. Consider using the+-- @'Lua.hslua_settable'@ ersatz function instead. Likewise, the+-- metamethod may not call a Haskell function unless the library was+-- compiled without @allow-unsafe-gc@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_settable>+foreign import ccall SAFTY "lua.h lua_settable"+ lua_settable :: Lua.State -> StackIndex {- ^ index -} -> IO ()+{-# WARNING lua_settable+ [ "This is an unsafe function, errors will lead to a program crash;"+ , "consider using hslua_settable instead."+ ] #-}++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_settop>+foreign import ccall unsafe "lua.h lua_settop"+ lua_settop :: Lua.State -> StackIndex {- ^ index -} -> IO ()++-- | Pops a value from the stack and sets it as the new value associated+-- to the full userdata at the given index.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_setuservalue>+foreign import ccall unsafe "lua.h lua_setuservalue"+ lua_setuservalue :: Lua.State -> StackIndex -> IO ()++-- | Returns the status of this Lua thread.+--+-- The status can be @'Lua.LUA_OK'@ for a normal thread, an+-- error value if the thread finished the execution of a @lua_resume@+-- with an error, or @'Lua.LUA_YIELD'@ if the thread is+-- suspended.+--+-- You can only call functions in threads with status+-- @'Lua.LUA_OK'@. You can resume threads with status+-- @'Lua.LUA_OK'@ (to start a new coroutine) or+-- @'Lua.LUA_YIELD'@ (to resume a coroutine).+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_status>.+foreign import ccall unsafe "lua.h lua_status"+ lua_status :: Lua.State -> IO StatusCode++-- | 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+-- @'lua_isboolean'@ to test the value's type.)+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_toboolean>+foreign import capi unsafe "lua.h lua_toboolean"+ lua_toboolean :: Lua.State -> StackIndex -> IO LuaBool++-- | Converts a value at the given index to a C function. That value+-- must be a C function; otherwise, returns @Nothing@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_tocfunction>+foreign import ccall unsafe "lua.h lua_tocfunction"+ lua_tocfunction :: Lua.State -> StackIndex -> IO CFunction++-- | 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, @lua_tointegerx@ returns @0@.+--+-- If the number is not an integer, it is truncated in some+-- non-specified way.+--+-- If @isnum@ is not @NULL@, its referent is assigned a boolean value+-- that indicates whether the operation succeeded.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_tointegerx>+foreign import ccall unsafe "lua.h lua_tointegerx"+ lua_tointegerx :: Lua.State+ -> StackIndex -- ^ index+ -> Ptr LuaBool -- ^ isnum+ -> IO Lua.Integer++-- | Converts the Lua value at the given index to a C string. If @len@+-- is not @NULL@, it sets the referent with the string length. The Lua+-- value must be a string or a number; otherwise, the function returns+-- @NULL@. If the value is a number, then @lua_tolstring@ also changes+-- the actual value in the stack to a string. (This change confuses+-- @lua_next@ when @lua_tolstring@ is applied to keys during a table+-- traversal.)+--+-- @lua_tolstring@ returns a pointer to a string inside the Lua state.+-- This string always has a zero ('\0') after its last character (as in+-- C), but can contain other zeros in its body.+--+-- Because Lua has garbage collection, there is no guarantee that the+-- pointer returned by @lua_tolstring@ will be valid after the+-- corresponding Lua value is removed from the stack.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_tolstring>+foreign import ccall SAFTY "lua.h lua_tolstring"+ lua_tolstring :: Lua.State+ -> StackIndex -- ^ index+ -> Ptr CSize -- ^ len+ -> IO (Ptr CChar)++-- | Converts the Lua value at the given index to the C type lua_Number+-- (see lua_Number). The Lua value must be a number or a string+-- convertible to a number (see §3.4.3); otherwise, lua_tonumberx+-- returns 0.+--+-- If @isnum@ is not @NULL@, its referent is assigned a boolean value+-- that indicates whether the operation succeeded.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_tonumberx>+foreign import ccall unsafe "lua.h lua_tonumberx"+ lua_tonumberx :: Lua.State+ -> StackIndex -- ^ index+ -> Ptr LuaBool -- ^ isnum+ -> IO Lua.Number++-- | 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.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_topointer>+foreign import ccall unsafe "lua.h lua_topointer"+ lua_topointer :: Lua.State -> StackIndex -> IO (Ptr ())++-- | 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 @'nullPtr'@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_tothread>+foreign import ccall unsafe "lua.h lua_tothread"+ lua_tothread :: Lua.State -> StackIndex -> IO Lua.State++-- | 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 @'nullPtr'@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_touserdata>+foreign import ccall unsafe "lua.h lua_touserdata"+ lua_touserdata :: Lua.State -> StackIndex -> IO (Ptr a)++-- | Returns the type of the value in the given valid index, or+-- @'Lua.LUA_TNONE'@ for a non-valid (but acceptable) index.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_type>+foreign import ccall unsafe "lua.h lua_type"+ lua_type :: Lua.State -> StackIndex -> IO TypeCode++-- | Returns the name of the type encoded by the value @tp@, which must+-- be one the values returned by @'lua_type'@.+--+-- <https://www.lua.org/manual/5.3/manual.html#lua_typename>+foreign import ccall unsafe "lua.h lua_typename"+ lua_typename :: Lua.State -> TypeCode {- ^ tp -} -> IO CString
+ src/Lua/Types.hsc view
@@ -0,0 +1,143 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE PatternSynonyms #-}+{-|+Module : Lua.Types+Copyright : © 2007–2012 Gracjan Polak;+ © 2012–2016 Ömer Sinan Ağacan;+ © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : non-portable (depends on GHC)++The core Lua types, including mappings of Lua types to Haskell.+-}+module Lua.Types+ ( State (..)+ , Reader+ , TypeCode (..)+ , CFunction+ , PreCFunction+ , LuaBool (..)+ , Integer (..)+ , Number (..)+ , StackIndex (..)+ , NumArgs (..)+ , NumResults (..)+ , OPCode (..)+ , StatusCode (..)+ -- * Garbage-Collection+ , GCCode (..)+ )+where++#include <lua.h>++import Prelude hiding (Integer)++import Data.Int (#{type LUA_INTEGER})+import Foreign.C (CChar, CInt, CSize)+import Foreign.Ptr (FunPtr, Ptr)+import Foreign.Storable (Storable)+import GHC.Generics (Generic)++-- | An opaque structure that points to a thread and indirectly (through the+-- thread) to the whole state of a Lua interpreter. The Lua library is fully+-- reentrant: it has no global variables. All information about a state is+-- accessible through this structure.+--+-- Synonym for @lua_State *@. See+-- <https://www.lua.org/manual/5.3/#lua_State lua_State>.+newtype State = State (Ptr ()) deriving (Eq, Generic)++-- | Type for C functions.+--+-- In order to communicate properly with Lua, a C function must use the+-- following protocol, which defines the way parameters and results are+-- passed: a C function receives its arguments from Lua in its stack in+-- direct order (the first argument is pushed first). So, when the+-- function starts, @'Lua.Functions.lua_gettop'@ returns the+-- number of arguments received by the function. The first argument (if+-- any) is at index 1 and its last argument is at index+-- @'Lua.Functions.lua_gettop'@. To return values to Lua, a C+-- function just pushes them onto the stack, in direct order (the first+-- result is pushed first), and returns the number of results. Any other+-- value in the stack below the results will be properly discarded by+-- Lua. Like a Lua function, a C function called by Lua can also return+-- many results.+--+-- See+-- <https://www.lua.org/manual/5.3/manual.html#lua_CFunction lua_CFunction>.+type CFunction = FunPtr PreCFunction++-- | Type of Haskell functions that can be turned into C functions.+--+-- This is the same as a dereferenced 'CFunction'.+type PreCFunction = State -> IO NumResults++-- | The reader function used by @'Lua.load'@.+-- Every time it needs another piece of the chunk, lua_load calls the+-- reader, passing along its data parameter. The reader must return a+-- pointer to a block of memory with a new piece of the chunk and set+-- size to the block size. The block must exist until the reader+-- function is called again. To signal the end of the chunk, the reader+-- must return @NULL@ or set size to zero. The reader function may+-- return pieces of any size greater than zero.+--+-- See <https://www.lua.org/manual/5.3/manual.html#lua_Reader lua_Reader>.+type Reader = FunPtr (State -> Ptr () -> Ptr CSize -> IO (Ptr CChar))++-- | The type of integers in Lua.+--+-- By default this type is @'Int64'@, but that can be changed to+-- different values in lua. (See @LUA_INT_TYPE@ in @luaconf.h@.)+--+-- See <https://www.lua.org/manual/5.3/manual.html#lua_Integer lua_Integer>.+newtype Integer = Integer #{type LUA_INTEGER}+ deriving (Bounded, Enum, Eq, Integral, Num, Ord, Real, Show)++-- | The type of floats in Lua.+--+-- By default this type is @'Double'@, but that can be changed in Lua to+-- a single float or a long double. (See @LUA_FLOAT_TYPE@ in+-- @luaconf.h@.)+--+-- See <https://www.lua.org/manual/5.3/manual.html#lua_Number lua_Number>.+newtype Number = Number #{type LUA_NUMBER}+ deriving (Eq, Floating, Fractional, Num, Ord, Real, RealFloat, RealFrac, Show)++-- | Boolean value returned by a Lua C API function. This is a @'CInt'@+-- and should be interpreted as @'False'@ iff the value is @0@, @'True'@+-- otherwise.+newtype LuaBool = LuaBool CInt+ deriving (Eq, Storable, Show)++-- | Integer code used to encode the type of a Lua value.+newtype TypeCode = TypeCode { fromTypeCode :: CInt }+ deriving (Eq, Ord, Show)++-- | Relational operator code.+newtype OPCode = OPCode CInt deriving (Eq, Storable)++-- | Integer code used to signal the status of a thread or computation.+newtype StatusCode = StatusCode CInt deriving (Eq, Storable)++-- | Garbage-collection options.+newtype GCCode = GCCode CInt deriving (Eq, Storable)++-- | A stack index+newtype StackIndex = StackIndex { fromStackIndex :: CInt }+ deriving (Enum, Eq, Num, Ord, Show)++--+-- Number of arguments and return values+--++-- | The number of arguments consumed curing a function call.+newtype NumArgs = NumArgs { fromNumArgs :: CInt }+ deriving (Eq, Num, Ord, Show)++-- | The number of results returned by a function call.+newtype NumResults = NumResults { fromNumResults :: CInt }+ deriving (Eq, Num, Ord, Show)
+ src/Lua/Userdata.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE CPP #-}+{-|+Module : Lua.Userdata+Copyright : © 2017-2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta+Portability : ForeignFunctionInterface++Bindings to HsLua-specific functions used to push Haskell values+as userdata.+-}+module Lua.Userdata+ ( hslua_fromuserdata+ , hslua_newhsuserdata+ , hslua_newudmetatable+ , hslua_putuserdata+ ) where++import Foreign.C (CInt (CInt), CString)+import Lua.Auxiliary (luaL_testudata)+import Lua.Primary (lua_newuserdata)+import Lua.Types+ ( LuaBool (..)+ , StackIndex (..)+ , State (..)+ )+import Foreign.Ptr (castPtr, nullPtr)+import Foreign.StablePtr (newStablePtr, deRefStablePtr, freeStablePtr)+import Foreign.Storable (peek, poke, sizeOf)++#ifdef ALLOW_UNSAFE_GC+#define SAFTY unsafe+#else+#define SAFTY safe+#endif++-- | Creates and registers a new metatable for a userdata-wrapped+-- Haskell value; checks whether a metatable of that name has been+-- registered yet and uses the registered table if possible.+foreign import ccall SAFTY "hsludata.h hslua_newudmetatable"+ hslua_newudmetatable :: State -- ^ Lua state+ -> CString -- ^ Userdata name (__name)+ -> IO LuaBool -- ^ True iff new metatable+ -- was created.++-- | Creates a new userdata wrapping the given Haskell object.+hslua_newhsuserdata :: State -> a -> IO ()+hslua_newhsuserdata l x = do+ xPtr <- newStablePtr x+ udPtr <- lua_newuserdata l (fromIntegral $ sizeOf xPtr)+ poke (castPtr udPtr) xPtr+{-# INLINABLE hslua_newhsuserdata #-}++-- | Retrieves a Haskell object from userdata at the given index.+-- The userdata /must/ have the given name.+hslua_fromuserdata :: State+ -> StackIndex -- ^ userdata index+ -> CString -- ^ name+ -> IO (Maybe a)+hslua_fromuserdata l idx name = do+ udPtr <- luaL_testudata l idx name+ if udPtr == nullPtr+ then return Nothing+ else Just <$> (peek (castPtr udPtr) >>= deRefStablePtr)+{-# INLINABLE hslua_fromuserdata #-}++-- | Replaces the Haskell value contained in the userdata value at+-- @index@. Checks that the userdata is of type @name@ and returns+-- 'True' on success, or 'False' otherwise.+hslua_putuserdata :: State+ -> StackIndex -- ^ index+ -> CString -- ^ name+ -> a -- ^ new Haskell value+ -> IO Bool+hslua_putuserdata l idx name x = do+ xPtr <- newStablePtr x+ udPtr <- luaL_testudata l idx name+ if udPtr == nullPtr+ then return False+ else do+ peek (castPtr udPtr) >>= freeStablePtr+ poke (castPtr udPtr) xPtr+ return True+{-# INLINABLE hslua_putuserdata #-}
+ test/Lua/UnsafeTests.hs view
@@ -0,0 +1,131 @@+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}+{-|+Module : Lua.UnsafeTests+Copyright : © 2021 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>+Stability : beta++Tests for bindings to unsafe functions.+-}+module Lua.UnsafeTests (tests) where++import Foreign.C.String (withCString, withCStringLen)+import Foreign.Ptr (nullPtr)+import Lua+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.HUnit (Assertion, HasCallStack, testCase, (@=?) )++-- | Tests for unsafe methods.+tests :: TestTree+tests = testGroup "Unsafe"+ [ testGroup "tables"+ [ "set and get integer field" =: do+ (-23, LUA_TNUMBER) `shouldBeResultOf` \l -> do+ lua_createtable l 0 0+ lua_pushinteger l 5+ lua_pushinteger l (-23)+ lua_settable l (nth 3)+ lua_pushinteger l 5+ tp <- lua_gettable l (nth 2)+ i <- lua_tointegerx l top nullPtr+ return (i, tp)++ , "get metamethod field" =: do+ (TRUE, LUA_TBOOLEAN) `shouldBeResultOf` \l -> do+ -- create table+ lua_createtable l 0 0+ -- create metatable+ lua_createtable l 0 0+ withCStringLen "__index" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ -- create index table+ lua_createtable l 0 0+ lua_pushinteger l 5+ lua_pushboolean l TRUE+ lua_rawset l (nth 3)+ -- set index table to "__index" in metatable+ lua_rawset l (nth 3)+ -- set metatable+ lua_setmetatable l (nth 2)+ -- access field in metatable+ lua_pushinteger l 5+ tp <- lua_gettable l (nth 2)+ b <- lua_toboolean l top+ return (b, tp)++ , "set metamethod field" =: do+ 1337 `shouldBeResultOf` \l -> do+ lua_createtable l 0 0 -- index table+ -- create table t+ lua_createtable l 0 0+ -- create metatable+ lua_createtable l 0 0+ withCStringLen "__newindex" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_pushvalue l (nth 4) -- index table+ -- set index table to "__newindex" in metatable+ lua_rawset l (nth 3)+ -- set metatable+ lua_setmetatable l (nth 2)++ -- set field n index table via __newindex on t+ lua_pushinteger l 1+ lua_pushinteger l 1337+ lua_settable l (nth 3)++ lua_pop l 1 -- drop table t+ lua_pushinteger l 1+ lua_rawget l (nth 2)+ lua_tointegerx l top nullPtr+ ]++ , testGroup "globals"+ [ "get global from base library" =:+ LUA_TFUNCTION `shouldBeResultOf` \l -> do+ luaL_openlibs l+ withCString "print" $ \ptr ->+ lua_getglobal l ptr++ , "set global" =:+ 13.37 `shouldBeResultOf` \l -> do+ lua_pushnumber l 13.37+ withCString "foo" $ lua_setglobal l+ lua_pushglobaltable l+ withCStringLen "foo" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_rawget l (nth 2)+ lua_tonumberx l top nullPtr+ ]++ , testGroup "next"+ [ "get next key from table" =:+ 41 `shouldBeResultOf` \l -> do+ -- create table {41}+ lua_createtable l 0 0+ lua_pushinteger l 41+ lua_rawseti l (nth 2) 1+ -- first key+ lua_pushnil l+ x <- lua_next l (nth 2)+ if x == FALSE+ then fail "expected truish return value"+ else lua_tonumberx l top nullPtr++ , "returns FALSE if table is empty" =:+ FALSE `shouldBeResultOf` \l -> do+ lua_createtable l 0 0+ lua_pushnil l+ lua_next l (nth 2)+ ]+ ]++infix 3 =:+(=:) :: String -> Assertion -> TestTree+(=:) = testCase++shouldBeResultOf :: (HasCallStack, Eq a, Show a)+ => a -> (State -> IO a) -> Assertion+shouldBeResultOf expected luaOp = do+ result <- withNewState luaOp+ expected @=? result
test/test-lua.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-| Module : Main Copyright : © 2021 Albert Krewinkel@@ -9,13 +10,21 @@ -} module Main (main) where +#ifdef ALLOW_UNSAFE_GC+import Control.Monad (void)+#else+import Control.Monad (forM_, void)+import Data.IORef (newIORef, readIORef, writeIORef)+#endif+ import Foreign.C.String (peekCString, withCStringLen)-import Foreign.Ptr (nullPtr)-import Foreign.Lua.Raw.Auxiliary-import Foreign.Lua.Raw.Functions-import Foreign.Lua.Raw.Types+import Foreign.Marshal (alloca)+import Foreign.Ptr (Ptr, nullPtr)+import Foreign.Storable as Storable+import Lua import Test.Tasty (TestTree, defaultMain, testGroup)-import Test.Tasty.HUnit ( Assertion, testCase, (@=?) )+import Test.Tasty.HUnit (Assertion, HasCallStack, assertBool, testCase, (@=?))+import qualified Lua.UnsafeTests -- | Runs tests. main :: IO ()@@ -24,70 +33,384 @@ -- | Specifications for Attributes parsing functions. tests :: TestTree tests = testGroup "lua"- [ testGroup "state"+ [ testGroup "thread" [ "create and close" =: do l <- hsluaL_newstate lua_close l++ , "newthread" =: do+ (5, 23) `shouldBeResultOf` \l -> do+ l1 <- lua_newthread l+ lua_pushnumber l 5+ lua_pushnumber l1 23+ (,) <$> lua_tonumberx l top nullPtr+ <*> lua_tonumberx l1 top nullPtr++ , "type check" =: do+ TRUE `shouldBeResultOf` \l -> do+ _ <- lua_newthread l+ lua_isthread l top++ , "thread type is LUA_TTHREAD" =: do+ LUA_TTHREAD `shouldBeResultOf` \l -> do+ _ <- lua_newthread l+ lua_type l top++ , "pushing" =: do+ LUA_TTHREAD `shouldBeResultOf` \l -> do+ newl <- lua_newthread l+ lua_pop l 1+ _ <- lua_pushthread newl+ lua_type newl top ] , testGroup "booleans" [ "push and retrieve" =: do- l <- hsluaL_newstate- lua_pushboolean l true- b <- lua_toboolean l (-1)- lua_close l- true @=? b+ TRUE `shouldBeResultOf` \l -> do+ lua_pushboolean l TRUE+ lua_toboolean l top + , "check" =: do+ TRUE `shouldBeResultOf` \l -> do+ lua_pushboolean l FALSE+ lua_isboolean l top+ , "type" =: do- l <- hsluaL_newstate- lua_pushboolean l false- ty <- lua_type l (-1)- lua_close l- TypeBoolean @=? toType ty+ LUA_TBOOLEAN `shouldBeResultOf` \l -> do+ lua_pushboolean l FALSE+ lua_type l top ] , testGroup "numbers"- [ "push and retrieve" =: do- l <- hsluaL_newstate- lua_pushinteger l 5- i <- lua_tointegerx l (-1) nullPtr- lua_close l- 5 @=? i+ [ "push and retrieve integer" =: do+ 5 `shouldBeResultOf` \l -> do+ lua_pushinteger l 5+ lua_tointegerx l top nullPtr + , "push and retrieve float" =: do+ (-0.1) `shouldBeResultOf` \l -> do+ lua_pushnumber l (-0.1)+ lua_tonumberx l top nullPtr++ , "check for integer" =: do+ (TRUE, FALSE) `shouldBeResultOf` \l -> do+ lua_pushinteger l 0+ t <- lua_isinteger l top+ lua_pushnil l+ f <- lua_isinteger l top+ return (t, f)++ , "check for number" =: do+ (TRUE, FALSE) `shouldBeResultOf` \l -> do+ lua_pushinteger l 0+ t <- lua_isnumber l top+ lua_pushnil l+ f <- lua_isnumber l top+ return (t, f)+ , "type" =: do- l <- hsluaL_newstate- lua_pushinteger l 0- ty <- lua_type l (-1)- lua_close l- TypeNumber @=? toType ty+ LUA_TNUMBER `shouldBeResultOf` \l -> do+ lua_pushinteger l 0+ lua_type l top ] + , testGroup "nil"+ [ "push and type check" =:+ (TRUE, FALSE) `shouldBeResultOf` \l -> do+ lua_pushnil l+ t <- lua_isnil l top+ lua_pushglobaltable l+ f <- lua_isnil l top+ return (t, f)++ , "type is LUA_TNIL" =:+ LUA_TNIL `shouldBeResultOf` \l -> do+ lua_pushnil l+ lua_type l top+ ]++ , testGroup "none"+ [ "invalid index is 'none'" =:+ TRUE `shouldBeResultOf` \l -> lua_isnone l 1++ , "valid index is not none" =:+ FALSE `shouldBeResultOf` \l -> do+ lua_pushnil l+ lua_isnone l 1++ , "invalid index has type LUA_TNONE" =:+ LUA_TNONE `shouldBeResultOf` \l -> lua_type l 9+ ]+ , testGroup "strings" [ "push and retrieve" =: do- l <- hsluaL_newstate- withCStringLen "testing" $ \(ptr, len) ->- lua_pushlstring l ptr (fromIntegral len)- str <- peekCString =<< lua_tolstring l (-1) nullPtr- lua_close l- "testing" @=? str+ "testing" `shouldBeResultOf` \l -> do+ withCStringLen "testing" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ peekCString =<< lua_tolstring l top nullPtr , "type" =: do- l <- hsluaL_newstate- withCStringLen "Olsen Olsen" $ \(ptr, len) ->- lua_pushlstring l ptr (fromIntegral len)- ty <- lua_type l (-1)- lua_close l- TypeString @=? toType ty+ LUA_TSTRING `shouldBeResultOf` \l -> do+ withCStringLen "Olsen Olsen" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_type l top ] + , testGroup "tables"+ [ "check type" =: do+ TRUE `shouldBeResultOf` \l -> do+ lua_createtable l 0 0+ lua_istable l top++ , "has type LUA_TTABLE" =: do+ LUA_TTABLE `shouldBeResultOf` \l -> do+ lua_createtable l 0 0+ lua_type l top++ , "set and get integer field" =: do+ (-23) `shouldBeResultOf` \l -> do+ lua_createtable l 0 0+ lua_pushinteger l 5+ lua_pushinteger l (-23)+ lua_rawset l (nth 3)+ lua_pushinteger l 5+ lua_rawget l (nth 2)+ lua_tointegerx l top nullPtr+ ]+ , testGroup "constants" [ "loadedTableRegistryField" =: ("_LOADED" @=? loadedTableRegistryField) , "preloadTableRegistryField" =: ("_PRELOAD" @=? preloadTableRegistryField) ]++ , testGroup "compare"+ [ "equality" =: do+ TRUE `shouldBeResultOf` \l -> do+ lua_pushinteger l 42+ lua_pushnumber l 42+ hslua_compare l (nth 2) (nth 1) LUA_OPEQ nullPtr++ , "less then" =: do+ TRUE `shouldBeResultOf` \l -> do+ lua_pushinteger l (-2)+ lua_pushnumber l 3+ hslua_compare l (nth 2) (nth 1) LUA_OPLT nullPtr++ , "not less then" =: do+ FALSE `shouldBeResultOf` \l -> do+ lua_pushinteger l 42+ lua_pushnumber l 42+ hslua_compare l (nth 2) (nth 1) LUA_OPLT nullPtr++ , "less then or equal" =: do+ TRUE `shouldBeResultOf` \l -> do+ lua_pushinteger l 23+ lua_pushnumber l 42+ alloca $ \statusPtr -> do+ result <- hslua_compare l (nth 2) (nth 1) LUA_OPLE statusPtr+ status <- Storable.peek statusPtr+ assertBool "comparison failed" (LUA_OK == status)+ return result+ ]++ , testGroup "function calling"+ [ "call `type(true)`" =: do+ "boolean" `shouldBeResultOf` \l -> do+ luaL_openlibs l+ -- push function `type`+ lua_pushglobaltable l+ withCStringLen "type" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_rawget l (nth 2)+ -- push boolean+ lua_pushboolean l TRUE+ status <- lua_pcall l (NumArgs 1) (NumResults 1) 0+ assertBool "call status" (status == LUA_OK)+ peekCString =<< lua_tolstring l top nullPtr++ , "call type" =: do+ (== LUA_ERRRUN) `shouldHoldForResultOf` \l -> do+ luaL_openlibs l+ -- push function `error`+ lua_pushglobaltable l+ withCStringLen "error" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_rawget l (nth 2)+ -- push boolean+ lua_pushboolean l TRUE+ lua_pcall l (NumArgs 1) (NumResults 1) 0+ ]++ , testGroup "garbage-collection"+ [ "stop, restart GC" =: do+ counts <- withNewState $ \l -> do+ lua_createtable l 0 0+ _ <- lua_gc l LUA_GCSTOP 0+ lua_pop l 1+ kb1 <- lua_gc l LUA_GCCOUNT 0+ b1 <- lua_gc l LUA_GCCOUNTB 0+ _ <- lua_gc l LUA_GCCOLLECT 0+ kb2 <- lua_gc l LUA_GCCOUNT 0+ b2 <- lua_gc l LUA_GCCOUNTB 0+ return (b1 + 1024 * kb1, b2 + 1024 * kb2)+ assertBool "first count should be larger" (uncurry (>) counts)+ , "count memory" =: do+ count <- withNewState $ \l -> do+ lua_gc l LUA_GCCOUNT 0+ assertBool "memory consumption not between 0 and 10 kB"+ (count > 0 && count < 10)+ ]++ , testGroup "ersatz functions"+ [ testGroup "globals"+ [ "get global from base library" =:+ LUA_TFUNCTION `shouldBeResultOf` \l -> do+ luaL_openlibs l+ withCStringLen "print" $ \(cstr, len) ->+ withAssertOK $ hslua_getglobal l cstr (fromIntegral len)++ , "set global" =:+ 13.37 `shouldBeResultOf` \l -> do+ lua_pushnumber l 13.37+ withCStringLen "foo" $ \(cstr, len) ->+ withAssertOK $ hslua_setglobal l cstr (fromIntegral len)+ lua_pushglobaltable l+ withCStringLen "foo" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_rawget l (nth 2)+ lua_tonumberx l top nullPtr+ ]++ , testGroup "table"+ [ "get metamethod field via ersatz function" =:+ (TRUE, LUA_TBOOLEAN) `shouldBeResultOf` \l -> do+ -- create table+ lua_createtable l 0 0+ -- create metatable+ lua_createtable l 0 0+ withCStringLen "__index" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ -- create index table+ lua_createtable l 0 0+ lua_pushinteger l 5+ lua_pushboolean l TRUE+ lua_rawset l (nth 3)+ -- set index table to "__index" in metatable+ lua_rawset l (nth 3)+ -- set metatable+ lua_setmetatable l (nth 2)+ -- access field in metatable+ lua_pushinteger l 5+ tp <- alloca $ \status ->+ hslua_gettable l (nth 2) status <*+ (peek status >>= assertBool "gettable status" . (== LUA_OK))+ b <- lua_toboolean l top+ return (b, tp)++ , "set metamethod field" =:+ 1337 `shouldBeResultOf` \l -> do+ lua_createtable l 0 0 -- index table+ -- create table t+ lua_createtable l 0 0+ -- create metatable+ lua_createtable l 0 0+ withCStringLen "__newindex" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ lua_pushvalue l (nth 4) -- index table+ -- set index table to "__newindex" in metatable+ lua_rawset l (nth 3)+ -- set metatable+ lua_setmetatable l (nth 2)++ -- set field n index table via __newindex on t+ lua_pushinteger l 1+ lua_pushinteger l 1337+ alloca $ \status ->+ hslua_settable l (nth 3) status <*+ (peek status >>= assertBool "settable status" . (== LUA_OK))++ lua_pop l 1 -- drop table t+ lua_pushinteger l 1+ lua_rawget l (nth 2)+ lua_tointegerx l top nullPtr+ ]+ ]++ , testGroup "Haskell functions"+ [ let add5 l = do+ n <- lua_tointegerx l top nullPtr+ lua_pushinteger l $ n + 5+ return (NumResults 1)+ in "call Haskell function" =: do+ 23 `shouldBeResultOf` \l -> do+ hslua_pushhsfunction l add5+ lua_pushinteger l 18+ void $ lua_pcall l (NumArgs 1) (NumResults 1) 0+ lua_tointegerx l (nth 1) nullPtr++#ifndef ALLOW_UNSAFE_GC+ , "Haskell function as finalizer" =: do+ msg <- newIORef "nope"+ let sendMessage _ = do+ writeIORef msg "HI MOM!"+ return (NumResults 0)+ "HI MOM!" `shouldBeResultOf` \l -> do+ -- create dummy table+ lua_createtable l 0 0+ -- create metatable with Haskell __gc function+ lua_createtable l 0 0+ withCStringLen "__gc" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ hslua_pushhsfunction l sendMessage+ lua_rawset l (nth 3)+ -- set metatable with finalizer+ lua_setmetatable l (nth 2)+ -- remove dummy table from stack so the GC to collect it+ lua_pop l 1+ -- perform a large number of operations to allow the GC to kick in.+ forM_ [1..100] $ \i -> do+ -- push some string+ withCStringLen "some nonesense" $ \(ptr, len) ->+ lua_pushlstring l ptr (fromIntegral len)+ -- create new table with integer field+ lua_createtable l 0 0+ lua_pushinteger l i+ lua_pushinteger l 23+ lua_rawset l (nth 3)+ -- set empty table as metatable+ lua_createtable l 0 0+ lua_setmetatable l (nth 2)+ -- remove table and strings from stack+ lua_pop l 2+ -- the GC should have run now, check the message+ readIORef msg+#endif+ ]++ , Lua.UnsafeTests.tests ] infix 3 =: (=:) :: String -> Assertion -> TestTree (=:) = testCase++shouldBeResultOf :: (HasCallStack, Eq a, Show a)+ => a -> (State -> IO a) -> Assertion+shouldBeResultOf expected luaOp = do+ result <- withNewState luaOp+ expected @=? result++shouldHoldForResultOf :: HasCallStack+ => (a -> Bool) -> (State -> IO a) -> Assertion+shouldHoldForResultOf predicate luaOp = do+ result <- withNewState luaOp+ assertBool "predicate does not hold" (predicate result)++withAssertOK :: HasCallStack => (Ptr StatusCode -> IO a) -> IO a+withAssertOK f =+ alloca $ \status -> do+ result <- f status+ peek status >>= assertBool "status not OK" . (== LUA_OK)+ return result