hslua 0.6.0 → 0.7.0
raw patch · 16 files changed
+852/−549 lines, 16 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Foreign.Lua.Api: LuaEQ :: LuaRelation
- Foreign.Lua.Api: LuaErrErr :: LuaStatus
- Foreign.Lua.Api: LuaErrGcmm :: LuaStatus
- Foreign.Lua.Api: LuaErrMem :: LuaStatus
- Foreign.Lua.Api: LuaErrRun :: LuaStatus
- Foreign.Lua.Api: LuaErrSyntax :: LuaStatus
- Foreign.Lua.Api: LuaLE :: LuaRelation
- Foreign.Lua.Api: LuaLT :: LuaRelation
- Foreign.Lua.Api: LuaOK :: LuaStatus
- Foreign.Lua.Api: LuaYield :: LuaStatus
- Foreign.Lua.Api: TBOOLEAN :: LTYPE
- Foreign.Lua.Api: TFUNCTION :: LTYPE
- Foreign.Lua.Api: TLIGHTUSERDATA :: LTYPE
- Foreign.Lua.Api: TNIL :: LTYPE
- Foreign.Lua.Api: TNONE :: LTYPE
- Foreign.Lua.Api: TNUMBER :: LTYPE
- Foreign.Lua.Api: TSTRING :: LTYPE
- Foreign.Lua.Api: TTABLE :: LTYPE
- Foreign.Lua.Api: TTHREAD :: LTYPE
- Foreign.Lua.Api: TUSERDATA :: LTYPE
- Foreign.Lua.Api: data LTYPE
- Foreign.Lua.Api: data LuaRelation
- Foreign.Lua.Api: data LuaStatus
- Foreign.Lua.Api: fromLuaRelation :: LuaRelation -> CInt
- Foreign.Lua.Api: fromLuaType :: LTYPE -> CInt
- Foreign.Lua.Api: toLuaStatus :: CInt -> LuaStatus
- Foreign.Lua.Api: toLuaType :: CInt -> LTYPE
- Foreign.Lua.Api.RawBindings: luaL_argerror :: LuaState -> CInt -> Ptr CChar -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_atpanic :: LuaState -> CFunction -> IO CFunction
- Foreign.Lua.Api.RawBindings: lua_callk :: LuaState -> CInt -> CInt -> CInt -> Ptr () -> IO ()
- Foreign.Lua.Api.RawBindings: lua_compare :: LuaState -> CInt -> CInt -> CInt -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_concat :: LuaState -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_dump :: LuaState -> FunPtr LuaWriter -> Ptr () -> IO ()
- Foreign.Lua.Api.RawBindings: lua_error :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_getfield :: LuaState -> CInt -> Ptr CChar -> IO ()
- Foreign.Lua.Api.RawBindings: lua_getglobal :: LuaState -> Ptr CChar -> IO ()
- Foreign.Lua.Api.RawBindings: lua_gettable :: LuaState -> CInt -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_load :: LuaState -> FunPtr LuaReader -> Ptr () -> Ptr CChar -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_newstate :: FunPtr LuaAlloc -> Ptr () -> IO LuaState
- Foreign.Lua.Api.RawBindings: lua_newthread :: LuaState -> IO LuaState
- Foreign.Lua.Api.RawBindings: lua_next :: LuaState -> CInt -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_base :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_debug :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_io :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_math :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_os :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_package :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_string :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_open_table :: LuaState -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_pushstring :: LuaState -> Ptr CChar -> IO ()
- Foreign.Lua.Api.RawBindings: lua_resume :: LuaState -> CInt -> CInt -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_setfield :: LuaState -> CInt -> Ptr CChar -> IO ()
- Foreign.Lua.Api.RawBindings: lua_setglobal :: LuaState -> Ptr CChar -> IO ()
- Foreign.Lua.Api.RawBindings: lua_settable :: LuaState -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_xmove :: LuaState -> LuaState -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_yieldk :: LuaState -> CInt -> CInt -> Ptr () -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_compare :: LuaState -> CInt -> CInt -> CInt -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_concat :: LuaState -> CInt -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_getfield :: LuaState -> CInt -> Ptr CChar -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_getglobal :: LuaState -> Ptr CChar -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_gettable :: LuaState -> CInt -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_next :: LuaState -> CInt -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_setfield :: LuaState -> CInt -> Ptr CChar -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_setglobal :: LuaState -> Ptr CChar -> IO CInt
- Foreign.Lua.Api.SafeBindings: hslua_settable :: LuaState -> CInt -> IO CInt
- Foreign.Lua.Api.Types: LuaEQ :: LuaRelation
- Foreign.Lua.Api.Types: LuaErrErr :: LuaStatus
- Foreign.Lua.Api.Types: LuaErrGcmm :: LuaStatus
- Foreign.Lua.Api.Types: LuaErrMem :: LuaStatus
- Foreign.Lua.Api.Types: LuaErrRun :: LuaStatus
- Foreign.Lua.Api.Types: LuaErrSyntax :: LuaStatus
- Foreign.Lua.Api.Types: LuaLE :: LuaRelation
- Foreign.Lua.Api.Types: LuaLT :: LuaRelation
- Foreign.Lua.Api.Types: LuaOK :: LuaStatus
- Foreign.Lua.Api.Types: LuaYield :: LuaStatus
- Foreign.Lua.Api.Types: TBOOLEAN :: LTYPE
- Foreign.Lua.Api.Types: TFUNCTION :: LTYPE
- Foreign.Lua.Api.Types: TLIGHTUSERDATA :: LTYPE
- Foreign.Lua.Api.Types: TNIL :: LTYPE
- Foreign.Lua.Api.Types: TNONE :: LTYPE
- Foreign.Lua.Api.Types: TNUMBER :: LTYPE
- Foreign.Lua.Api.Types: TSTRING :: LTYPE
- Foreign.Lua.Api.Types: TTABLE :: LTYPE
- Foreign.Lua.Api.Types: TTHREAD :: LTYPE
- Foreign.Lua.Api.Types: TUSERDATA :: LTYPE
- Foreign.Lua.Api.Types: data LTYPE
- Foreign.Lua.Api.Types: data LuaRelation
- Foreign.Lua.Api.Types: data LuaStatus
- Foreign.Lua.Api.Types: fromLuaRelation :: LuaRelation -> CInt
- Foreign.Lua.Api.Types: fromLuaType :: LTYPE -> CInt
- Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.LTYPE
- Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.LuaRelation
- Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.LuaStatus
- Foreign.Lua.Api.Types: instance GHC.Classes.Ord Foreign.Lua.Api.Types.LTYPE
- Foreign.Lua.Api.Types: instance GHC.Classes.Ord Foreign.Lua.Api.Types.LuaRelation
- Foreign.Lua.Api.Types: instance GHC.Enum.Bounded Foreign.Lua.Api.Types.LTYPE
- Foreign.Lua.Api.Types: instance GHC.Enum.Enum Foreign.Lua.Api.Types.LTYPE
- Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.LTYPE
- Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.LuaRelation
- Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.LuaStatus
- Foreign.Lua.Api.Types: toLuaStatus :: CInt -> LuaStatus
- Foreign.Lua.Api.Types: toLuaType :: CInt -> LTYPE
- Foreign.Lua.Api.Types: type LuaAlloc = Ptr () -> Ptr () -> CSize -> CSize -> IO (Ptr ())
- Foreign.Lua.Api.Types: type LuaReader = Ptr () -> Ptr () -> Ptr CSize -> IO (Ptr CChar)
- Foreign.Lua.Api.Types: type LuaWriter = LuaState -> Ptr CChar -> CSize -> Ptr () -> IO CInt
+ Foreign.Lua: pushList :: ToLuaStack a => [a] -> Lua ()
+ Foreign.Lua: toList :: FromLuaStack a => StackIndex -> Lua [a]
+ Foreign.Lua.Api: EQ :: RelationalOperator
+ Foreign.Lua.Api: ErrErr :: Status
+ Foreign.Lua.Api: ErrFile :: Status
+ Foreign.Lua.Api: ErrGcmm :: Status
+ Foreign.Lua.Api: ErrMem :: Status
+ Foreign.Lua.Api: ErrRun :: Status
+ Foreign.Lua.Api: ErrSyntax :: Status
+ Foreign.Lua.Api: LE :: RelationalOperator
+ Foreign.Lua.Api: LT :: RelationalOperator
+ Foreign.Lua.Api: OK :: Status
+ Foreign.Lua.Api: TypeBoolean :: Type
+ Foreign.Lua.Api: TypeCode :: CInt -> TypeCode
+ Foreign.Lua.Api: TypeFunction :: Type
+ Foreign.Lua.Api: TypeLightUserdata :: Type
+ Foreign.Lua.Api: TypeNil :: Type
+ Foreign.Lua.Api: TypeNone :: Type
+ Foreign.Lua.Api: TypeNumber :: Type
+ Foreign.Lua.Api: TypeString :: Type
+ Foreign.Lua.Api: TypeTable :: Type
+ Foreign.Lua.Api: TypeThread :: Type
+ Foreign.Lua.Api: TypeUserdata :: Type
+ Foreign.Lua.Api: Yield :: Status
+ Foreign.Lua.Api: [fromTypeCode] :: TypeCode -> CInt
+ Foreign.Lua.Api: data RelationalOperator
+ Foreign.Lua.Api: data Status
+ Foreign.Lua.Api: data Type
+ Foreign.Lua.Api: dofile :: FilePath -> Lua Status
+ Foreign.Lua.Api: dostring :: String -> Lua Status
+ Foreign.Lua.Api: fromRelationalOperator :: RelationalOperator -> CInt
+ Foreign.Lua.Api: fromType :: Type -> TypeCode
+ Foreign.Lua.Api: newtype TypeCode
+ Foreign.Lua.Api: toStatus :: StatusCode -> Status
+ Foreign.Lua.Api: toType :: TypeCode -> Type
+ Foreign.Lua.Api: tointegerx :: StackIndex -> Lua (Maybe LuaInteger)
+ Foreign.Lua.Api: tonumberx :: StackIndex -> Lua (Maybe LuaNumber)
+ Foreign.Lua.Api.RawBindings: hslua_compare :: LuaState -> StackIndex -> StackIndex -> CInt -> IO (Failable LuaBool)
+ Foreign.Lua.Api.RawBindings: hslua_concat :: LuaState -> NumArgs -> IO (Failable LuaBool)
+ Foreign.Lua.Api.RawBindings: hslua_getfield :: LuaState -> StackIndex -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: hslua_getglobal :: LuaState -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: hslua_gettable :: LuaState -> StackIndex -> IO CInt
+ Foreign.Lua.Api.RawBindings: hslua_next :: LuaState -> StackIndex -> IO (Failable LuaBool)
+ Foreign.Lua.Api.RawBindings: hslua_setfield :: LuaState -> StackIndex -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: hslua_setglobal :: LuaState -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: hslua_settable :: LuaState -> StackIndex -> IO CInt
+ Foreign.Lua.Api.Types: EQ :: RelationalOperator
+ Foreign.Lua.Api.Types: ErrErr :: Status
+ Foreign.Lua.Api.Types: ErrFile :: Status
+ Foreign.Lua.Api.Types: ErrGcmm :: Status
+ Foreign.Lua.Api.Types: ErrMem :: Status
+ Foreign.Lua.Api.Types: ErrRun :: Status
+ Foreign.Lua.Api.Types: ErrSyntax :: Status
+ Foreign.Lua.Api.Types: LE :: RelationalOperator
+ Foreign.Lua.Api.Types: LT :: RelationalOperator
+ Foreign.Lua.Api.Types: LuaBool :: CInt -> LuaBool
+ Foreign.Lua.Api.Types: OK :: Status
+ Foreign.Lua.Api.Types: StatusCode :: CInt -> StatusCode
+ Foreign.Lua.Api.Types: TypeBoolean :: Type
+ Foreign.Lua.Api.Types: TypeCode :: CInt -> TypeCode
+ Foreign.Lua.Api.Types: TypeFunction :: Type
+ Foreign.Lua.Api.Types: TypeLightUserdata :: Type
+ Foreign.Lua.Api.Types: TypeNil :: Type
+ Foreign.Lua.Api.Types: TypeNone :: Type
+ Foreign.Lua.Api.Types: TypeNumber :: Type
+ Foreign.Lua.Api.Types: TypeString :: Type
+ Foreign.Lua.Api.Types: TypeTable :: Type
+ Foreign.Lua.Api.Types: TypeThread :: Type
+ Foreign.Lua.Api.Types: TypeUserdata :: Type
+ Foreign.Lua.Api.Types: Yield :: Status
+ Foreign.Lua.Api.Types: [fromTypeCode] :: TypeCode -> CInt
+ Foreign.Lua.Api.Types: data RelationalOperator
+ Foreign.Lua.Api.Types: data Status
+ Foreign.Lua.Api.Types: data Type
+ Foreign.Lua.Api.Types: fromLuaBool :: LuaBool -> Bool
+ Foreign.Lua.Api.Types: fromRelationalOperator :: RelationalOperator -> CInt
+ Foreign.Lua.Api.Types: fromType :: Type -> TypeCode
+ Foreign.Lua.Api.Types: instance Foreign.Storable.Storable Foreign.Lua.Api.Types.LuaBool
+ Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.LuaBool
+ Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.RelationalOperator
+ Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.Status
+ Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.StatusCode
+ Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.Type
+ Foreign.Lua.Api.Types: instance GHC.Classes.Eq Foreign.Lua.Api.Types.TypeCode
+ Foreign.Lua.Api.Types: instance GHC.Classes.Ord Foreign.Lua.Api.Types.RelationalOperator
+ Foreign.Lua.Api.Types: instance GHC.Classes.Ord Foreign.Lua.Api.Types.Type
+ Foreign.Lua.Api.Types: instance GHC.Classes.Ord Foreign.Lua.Api.Types.TypeCode
+ Foreign.Lua.Api.Types: instance GHC.Enum.Bounded Foreign.Lua.Api.Types.Type
+ Foreign.Lua.Api.Types: instance GHC.Enum.Enum Foreign.Lua.Api.Types.Type
+ Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.RelationalOperator
+ Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.Status
+ Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.Type
+ Foreign.Lua.Api.Types: instance GHC.Show.Show Foreign.Lua.Api.Types.TypeCode
+ Foreign.Lua.Api.Types: newtype LuaBool
+ Foreign.Lua.Api.Types: newtype StatusCode
+ Foreign.Lua.Api.Types: newtype TypeCode
+ Foreign.Lua.Api.Types: toLuaBool :: Bool -> LuaBool
+ Foreign.Lua.Api.Types: toStatus :: StatusCode -> Status
+ Foreign.Lua.Api.Types: toType :: TypeCode -> Type
+ Foreign.Lua.Api.Types: type Failable a = CInt
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b)
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b, Foreign.Lua.Types.FromLuaStack.FromLuaStack c) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b, c)
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b, Foreign.Lua.Types.FromLuaStack.FromLuaStack c, Foreign.Lua.Types.FromLuaStack.FromLuaStack d) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b, c, d)
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b, Foreign.Lua.Types.FromLuaStack.FromLuaStack c, Foreign.Lua.Types.FromLuaStack.FromLuaStack d, Foreign.Lua.Types.FromLuaStack.FromLuaStack e) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b, c, d, e)
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b, Foreign.Lua.Types.FromLuaStack.FromLuaStack c, Foreign.Lua.Types.FromLuaStack.FromLuaStack d, Foreign.Lua.Types.FromLuaStack.FromLuaStack e, Foreign.Lua.Types.FromLuaStack.FromLuaStack f) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b, c, d, e, f)
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b, Foreign.Lua.Types.FromLuaStack.FromLuaStack c, Foreign.Lua.Types.FromLuaStack.FromLuaStack d, Foreign.Lua.Types.FromLuaStack.FromLuaStack e, Foreign.Lua.Types.FromLuaStack.FromLuaStack f, Foreign.Lua.Types.FromLuaStack.FromLuaStack g) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b, c, d, e, f, g)
+ Foreign.Lua.Types.FromLuaStack: instance (Foreign.Lua.Types.FromLuaStack.FromLuaStack a, Foreign.Lua.Types.FromLuaStack.FromLuaStack b, Foreign.Lua.Types.FromLuaStack.FromLuaStack c, Foreign.Lua.Types.FromLuaStack.FromLuaStack d, Foreign.Lua.Types.FromLuaStack.FromLuaStack e, Foreign.Lua.Types.FromLuaStack.FromLuaStack f, Foreign.Lua.Types.FromLuaStack.FromLuaStack g, Foreign.Lua.Types.FromLuaStack.FromLuaStack h) => Foreign.Lua.Types.FromLuaStack.FromLuaStack (a, b, c, d, e, f, g, h)
+ Foreign.Lua.Types.FromLuaStack: toList :: FromLuaStack a => StackIndex -> Lua [a]
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b)
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b, Foreign.Lua.Types.ToLuaStack.ToLuaStack c) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b, c)
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b, Foreign.Lua.Types.ToLuaStack.ToLuaStack c, Foreign.Lua.Types.ToLuaStack.ToLuaStack d) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b, c, d)
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b, Foreign.Lua.Types.ToLuaStack.ToLuaStack c, Foreign.Lua.Types.ToLuaStack.ToLuaStack d, Foreign.Lua.Types.ToLuaStack.ToLuaStack e) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b, c, d, e)
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b, Foreign.Lua.Types.ToLuaStack.ToLuaStack c, Foreign.Lua.Types.ToLuaStack.ToLuaStack d, Foreign.Lua.Types.ToLuaStack.ToLuaStack e, Foreign.Lua.Types.ToLuaStack.ToLuaStack f) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b, c, d, e, f)
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b, Foreign.Lua.Types.ToLuaStack.ToLuaStack c, Foreign.Lua.Types.ToLuaStack.ToLuaStack d, Foreign.Lua.Types.ToLuaStack.ToLuaStack e, Foreign.Lua.Types.ToLuaStack.ToLuaStack f, Foreign.Lua.Types.ToLuaStack.ToLuaStack g) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b, c, d, e, f, g)
+ Foreign.Lua.Types.ToLuaStack: instance (Foreign.Lua.Types.ToLuaStack.ToLuaStack a, Foreign.Lua.Types.ToLuaStack.ToLuaStack b, Foreign.Lua.Types.ToLuaStack.ToLuaStack c, Foreign.Lua.Types.ToLuaStack.ToLuaStack d, Foreign.Lua.Types.ToLuaStack.ToLuaStack e, Foreign.Lua.Types.ToLuaStack.ToLuaStack f, Foreign.Lua.Types.ToLuaStack.ToLuaStack g, Foreign.Lua.Types.ToLuaStack.ToLuaStack h) => Foreign.Lua.Types.ToLuaStack.ToLuaStack (a, b, c, d, e, f, g, h)
+ Foreign.Lua.Types.ToLuaStack: pushList :: ToLuaStack a => [a] -> Lua ()
- Foreign.Lua.Api: compare :: StackIndex -> StackIndex -> LuaRelation -> Lua Bool
+ Foreign.Lua.Api: compare :: StackIndex -> StackIndex -> RelationalOperator -> Lua Bool
- Foreign.Lua.Api: concat :: Int -> Lua ()
+ Foreign.Lua.Api: concat :: NumArgs -> Lua ()
- Foreign.Lua.Api: loadfile :: String -> Lua Int
+ Foreign.Lua.Api: loadfile :: String -> Lua Status
- Foreign.Lua.Api: loadstring :: String -> Lua LuaStatus
+ Foreign.Lua.Api: loadstring :: String -> Lua Status
- Foreign.Lua.Api: ltype :: StackIndex -> Lua LTYPE
+ Foreign.Lua.Api: ltype :: StackIndex -> Lua Type
- Foreign.Lua.Api: pcall :: NumArgs -> NumResults -> Maybe StackIndex -> Lua LuaStatus
+ Foreign.Lua.Api: pcall :: NumArgs -> NumResults -> Maybe StackIndex -> Lua Status
- Foreign.Lua.Api: status :: Lua LuaStatus
+ Foreign.Lua.Api: status :: Lua Status
- Foreign.Lua.Api: type CFunction = FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api: type CFunction = FunPtr (LuaState -> IO NumResults)
- Foreign.Lua.Api: typename :: LTYPE -> Lua String
+ Foreign.Lua.Api: typename :: Type -> Lua String
- Foreign.Lua.Api.RawBindings: luaL_loadfilex :: LuaState -> Ptr CChar -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: luaL_loadfilex :: LuaState -> Ptr CChar -> Ptr CChar -> IO StatusCode
- Foreign.Lua.Api.RawBindings: luaL_loadstring :: LuaState -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: luaL_loadstring :: LuaState -> Ptr CChar -> IO StatusCode
- Foreign.Lua.Api.RawBindings: luaL_newmetatable :: LuaState -> Ptr CChar -> IO CInt
+ Foreign.Lua.Api.RawBindings: luaL_newmetatable :: LuaState -> Ptr CChar -> IO LuaBool
- Foreign.Lua.Api.RawBindings: luaL_ref :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: luaL_ref :: LuaState -> StackIndex -> IO CInt
- Foreign.Lua.Api.RawBindings: luaL_unref :: LuaState -> CInt -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: luaL_unref :: LuaState -> StackIndex -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_checkstack :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_checkstack :: LuaState -> StackIndex -> IO LuaBool
- Foreign.Lua.Api.RawBindings: lua_copy :: LuaState -> CInt -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_copy :: LuaState -> StackIndex -> StackIndex -> IO ()
- Foreign.Lua.Api.RawBindings: lua_getmetatable :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_getmetatable :: LuaState -> StackIndex -> IO CInt
- Foreign.Lua.Api.RawBindings: lua_gettop :: LuaState -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_gettop :: LuaState -> IO StackIndex
- Foreign.Lua.Api.RawBindings: lua_iscfunction :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_iscfunction :: LuaState -> StackIndex -> IO LuaBool
- Foreign.Lua.Api.RawBindings: lua_isnumber :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_isnumber :: LuaState -> StackIndex -> IO LuaBool
- Foreign.Lua.Api.RawBindings: lua_isstring :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_isstring :: LuaState -> StackIndex -> IO LuaBool
- Foreign.Lua.Api.RawBindings: lua_isuserdata :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_isuserdata :: LuaState -> StackIndex -> IO LuaBool
- Foreign.Lua.Api.RawBindings: lua_open_base_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_base_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_debug_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_debug_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_io_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_io_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_math_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_math_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_os_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_os_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_package_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_package_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_string_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_string_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_open_table_ptr :: FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.RawBindings: lua_open_table_ptr :: CFunction
- Foreign.Lua.Api.RawBindings: lua_pcallk :: LuaState -> CInt -> CInt -> CInt -> CInt -> Ptr () -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_pcallk :: LuaState -> NumArgs -> NumResults -> StackIndex -> CInt -> Ptr () -> IO StatusCode
- Foreign.Lua.Api.RawBindings: lua_pushboolean :: LuaState -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_pushboolean :: LuaState -> LuaBool -> IO ()
- Foreign.Lua.Api.RawBindings: lua_pushcclosure :: LuaState -> CFunction -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_pushcclosure :: LuaState -> CFunction -> NumArgs -> IO ()
- Foreign.Lua.Api.RawBindings: lua_pushvalue :: LuaState -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_pushvalue :: LuaState -> StackIndex -> IO ()
- Foreign.Lua.Api.RawBindings: lua_rawequal :: LuaState -> CInt -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_rawequal :: LuaState -> StackIndex -> StackIndex -> IO LuaBool
- Foreign.Lua.Api.RawBindings: lua_rawget :: LuaState -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_rawget :: LuaState -> StackIndex -> IO ()
- Foreign.Lua.Api.RawBindings: lua_rawgeti :: LuaState -> CInt -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_rawgeti :: LuaState -> StackIndex -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_rawlen :: LuaState -> CInt -> IO CSize
+ Foreign.Lua.Api.RawBindings: lua_rawlen :: LuaState -> StackIndex -> IO CSize
- Foreign.Lua.Api.RawBindings: lua_rawset :: LuaState -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_rawset :: LuaState -> StackIndex -> IO ()
- Foreign.Lua.Api.RawBindings: lua_rawseti :: LuaState -> CInt -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_rawseti :: LuaState -> StackIndex -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_rotate :: LuaState -> CInt -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_rotate :: LuaState -> StackIndex -> CInt -> IO ()
- Foreign.Lua.Api.RawBindings: lua_setmetatable :: LuaState -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_setmetatable :: LuaState -> StackIndex -> IO ()
- Foreign.Lua.Api.RawBindings: lua_settop :: LuaState -> CInt -> IO ()
+ Foreign.Lua.Api.RawBindings: lua_settop :: LuaState -> StackIndex -> IO ()
- Foreign.Lua.Api.RawBindings: lua_status :: LuaState -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_status :: LuaState -> IO StatusCode
- Foreign.Lua.Api.RawBindings: lua_toboolean :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_toboolean :: LuaState -> StackIndex -> IO StackIndex
- Foreign.Lua.Api.RawBindings: lua_tocfunction :: LuaState -> CInt -> IO CFunction
+ Foreign.Lua.Api.RawBindings: lua_tocfunction :: LuaState -> StackIndex -> IO CFunction
- Foreign.Lua.Api.RawBindings: lua_tointegerx :: LuaState -> CInt -> CInt -> IO LuaInteger
+ Foreign.Lua.Api.RawBindings: lua_tointegerx :: LuaState -> StackIndex -> Ptr LuaBool -> IO LuaInteger
- Foreign.Lua.Api.RawBindings: lua_tolstring :: LuaState -> CInt -> Ptr CSize -> IO (Ptr CChar)
+ Foreign.Lua.Api.RawBindings: lua_tolstring :: LuaState -> StackIndex -> Ptr CSize -> IO (Ptr CChar)
- Foreign.Lua.Api.RawBindings: lua_tonumberx :: LuaState -> CInt -> CInt -> IO LuaNumber
+ Foreign.Lua.Api.RawBindings: lua_tonumberx :: LuaState -> StackIndex -> Ptr LuaBool -> IO LuaNumber
- Foreign.Lua.Api.RawBindings: lua_topointer :: LuaState -> CInt -> IO (Ptr ())
+ Foreign.Lua.Api.RawBindings: lua_topointer :: LuaState -> StackIndex -> IO (Ptr ())
- Foreign.Lua.Api.RawBindings: lua_tothread :: LuaState -> CInt -> IO LuaState
+ Foreign.Lua.Api.RawBindings: lua_tothread :: LuaState -> StackIndex -> IO LuaState
- Foreign.Lua.Api.RawBindings: lua_touserdata :: LuaState -> CInt -> IO (Ptr a)
+ Foreign.Lua.Api.RawBindings: lua_touserdata :: LuaState -> StackIndex -> IO (Ptr a)
- Foreign.Lua.Api.RawBindings: lua_type :: LuaState -> CInt -> IO CInt
+ Foreign.Lua.Api.RawBindings: lua_type :: LuaState -> StackIndex -> IO TypeCode
- Foreign.Lua.Api.RawBindings: lua_typename :: LuaState -> CInt -> IO (Ptr CChar)
+ Foreign.Lua.Api.RawBindings: lua_typename :: LuaState -> TypeCode -> IO (Ptr CChar)
- Foreign.Lua.Api.Types: type CFunction = FunPtr (LuaState -> IO CInt)
+ Foreign.Lua.Api.Types: type CFunction = FunPtr (LuaState -> IO NumResults)
Files
- CHANGELOG.md +61/−1
- hslua.cabal +5/−3
- src/Foreign/Lua.hs +2/−0
- src/Foreign/Lua/Api.hs +151/−111
- src/Foreign/Lua/Api/RawBindings.hsc +134/−211
- src/Foreign/Lua/Api/SafeBindings.hsc +0/−73
- src/Foreign/Lua/Api/Types.hsc +134/−91
- src/Foreign/Lua/FunctionCalling.hs +1/−1
- src/Foreign/Lua/Types/FromLuaStack.hs +131/−27
- src/Foreign/Lua/Types/ToLuaStack.hs +97/−4
- test/Foreign/Lua/ApiTest.hs +102/−25
- test/Foreign/Lua/TypesTest.hs +22/−0
- test/Foreign/LuaTest.hs +2/−2
- test/lua/error.lua +1/−0
- test/lua/example.lua +8/−0
- test/lua/syntax-error.lua +1/−0
CHANGELOG.md view
@@ -1,5 +1,65 @@ ## Changelog+### 0.7.0 +- Tuples from pairs to octuples have been made instances of `FromLuaStack` and+ `ToLuaStack`.+- New functions `dostring` and `dofile` are provided to load and run strings and+ files in a single step.+- `LuaStatus` was renamed to `Status`, the *Lua* prefix was removed from its+ type constructors.+- The constructor `ErrFile` was added to `Status`. It is returned by `loadfile`+ if the file cannot be read.+- Remove unused FFI bindings and unused types, including all functions unsafe to+ use from within Haskell and the library functions added with 0.5.0. Users with+ special requirements should define their own wrappers and raw bindings.+- The module *Foreign.Lua.Api.SafeBindings* was merge into+ *Foreign.Lua.Api.RawBindings*.+- FFI bindings are changed to use newtypes where sensible, most notably+ `StackIndex`, `NumArgs`, and `NumResults`, but also the newly introduced+ newtypes `StatusCode`, `TypeCode`, and `LuaBool`.+- Add functions `tointegerx` and `tonumberx` which can be used to get and check+ values from the stack in a single step.+- The signature of `concat` was changed from `Int -> Lua ()` to+ `NumArgs -> Lua ()`.+- The signature of `loadfile` was changed from `String -> Lua Int` to+ `String -> Lua Status`. +- The type `LTYPE` was renamed to `Type`, its constructors were renamed to+ follow the pattern `Type<Typename>`. `LuaRelation` was renamed to+ `RelationalOperator`, the *Lua* prefix was removed from its constructors.+- Add function `tolist` to allow getting a generic list from the stack without+ having to worry about the overlapping instance with `[Char]`.+++### 0.6.0++* Supported Lua Versions now include Lua 5.2 and Lua 5.3. LuaJIT and Lua 5.1+ remain supported as well.+* Flag `use-pkgconfig` was added to allow discovery of library and include paths+ via pkg-config. Setting a specific Lua version flag now implies `system-lua`.+ (Sean Proctor)+* The module was renamed from `Scripting.Lua` to `Foreign.Lua`. The code is now+ split over multiple sub-modules. Files processed with hsc2hs are restricted to+ Foreign.Lua.Api.+* A `Lua` monad (reader monad over LuaState) is introduced. Functions which took+ a LuaState as their first argument are changed into monadic functions within+ that monad.+* Error handling has been redesigned completely. A new LuaException was+ introduced and is thrown in unexpected situations. Errors in lua which are+ leading to a `longjmp` are now caught with the help of additional C wrapper+ functions. Those no longer lead to uncontrolled program termination but are+ converted into a LuaException.+* `peek` no longer returns `Maybe a` but just `a`. A LuaException is thrown if+ an error occurs (i.e. in situtations where Nothing would have been returned+ previously).+* The `StackValue` typeclass has been split into `FromLuaStack` and+ `ToLuaStack`. Instances not satisfying the law `x == push x *> peek (-1)` have+ been dropped.+* Documentation of API functions was improved. Most docstrings have been copied+ from the official Lua manual, enriched with proper markup and links, and+ changed to properly describe hslua specifics when necessary.+* Example programs have been moved to a separate repository.+* Unused files were removed. (Sean Proctor)+ ### 0.5.0 * New raw functions for `luaopen_base`, `luaopen_package`, `luaopen_string`,@@ -10,7 +70,7 @@ * Drop support for GHC versions < 7.8, avoid compiler warnings. * Ensure no symbols are stripped when linking the bundled lua interpreter. * Simplify `tostring` function definition. (Sean Proctor)-* Explicitly decprecate `strlen`. (Sean Proctor)+* Explicitly deprecate `strlen`. (Sean Proctor) * Add links to lua documentation for functions wrapping the official lua C API. (Sean Proctor).
hslua.cabal view
@@ -1,5 +1,5 @@ name: hslua-version: 0.6.0+version: 0.7.0 stability: beta cabal-version: >= 1.8 license: MIT@@ -19,7 +19,7 @@ 5.3.4. If you want to link it with a system-wide Lua installation, use the @system-lua@ flag. .- <https://github.com/tarleb/hslua-examples Example programs>+ <https://github.com/hslua/hslua-examples Example programs> are available in a separate repository. category: Foreign extra-source-files: lua-5.3.4/*.h@@ -27,6 +27,9 @@ README.md CHANGELOG.md COPYRIGHT+ test/lua/syntax-error.lua+ test/lua/error.lua+ test/lua/example.lua source-repository head type: git@@ -69,7 +72,6 @@ , Foreign.Lua.Api.Constants , Foreign.Lua.Api.RawBindings , Foreign.Lua.Api.Types- , Foreign.Lua.Api.SafeBindings , Foreign.Lua.FunctionCalling , Foreign.Lua.Types , Foreign.Lua.Types.Error
src/Foreign/Lua.hs view
@@ -42,9 +42,11 @@ -- * Receiving values from Lua stack (Lua → Haskell) , FromLuaStack (..) , peekEither+ , toList , pairsFromTable -- * Pushing values to Lua stack (Haskell → Lua) , ToLuaStack (..)+ , pushList -- * Calling Functions , PreCFunction , HaskellFunction
src/Foreign/Lua/Api.hs view
@@ -67,9 +67,10 @@ , replace , checkstack -- ** types and type checks- , LTYPE (..)- , fromLuaType- , toLuaType+ , Type (..)+ , TypeCode (..)+ , fromType+ , toType , ltype , typename , isboolean@@ -88,7 +89,9 @@ , toboolean , tocfunction , tointeger+ , tointegerx , tonumber+ , tonumberx , topointer , tostring , tothread@@ -97,8 +100,8 @@ , rawlen , strlen -- ** Comparison and arithmetic functions- , LuaRelation (..)- , fromLuaRelation+ , RelationalOperator (..)+ , fromRelationalOperator , compare , equal , lessthan@@ -136,8 +139,8 @@ , loadfile , loadstring -- ** Coroutine functions- , LuaStatus (..)- , toLuaStatus+ , Status (..)+ , toStatus , status -- ** garbage-collection function and options , GCCONTROL (..)@@ -158,22 +161,24 @@ , openstring , opentable -- * Auxiliary library+ , dostring+ , dofile , newmetatable , ref , unref ) where -import Prelude hiding (compare, concat)+import Prelude hiding (EQ, LT, compare, concat) import Control.Monad+import Data.Maybe (fromMaybe) import Foreign.C import Foreign.Lua.Api.Constants import Foreign.Lua.Api.RawBindings-import Foreign.Lua.Api.SafeBindings import Foreign.Lua.Api.Types import Foreign.Lua.Types.Error import Foreign.Lua.Types.Lua-import Foreign.Marshal.Alloc+import Foreign.Marshal.Alloc (alloca) import Foreign.Ptr import qualified Data.ByteString as B@@ -186,8 +191,7 @@ -- -- | Throw a lua error if the computation signaled a failure.--- | Throw a lua error if the computation signaled a failure.-throwOnError :: CInt -> Lua CInt+throwOnError :: Failable a -> Lua CInt throwOnError x = if x < 0 then throwTopMessageAsError@@ -242,7 +246,7 @@ call :: NumArgs -> NumResults -> Lua () call nargs nresults = do res <- pcall nargs nresults Nothing- when (res /= LuaOK) throwTopMessageAsError+ when (res /= OK) throwTopMessageAsError -- | 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@@ -255,7 +259,7 @@ -- This is a wrapper function of -- <https://www.lua.org/manual/5.3/manual.html#lua_checkstack lua_checkstack>. checkstack :: Int -> Lua Bool-checkstack n = liftLua $ \l -> (/= 0) <$> lua_checkstack l (fromIntegral n)+checkstack n = liftLua $ \l -> fromLuaBool <$> lua_checkstack l (fromIntegral n) -- | Destroys all objects in the given Lua state (calling the corresponding -- garbage-collection metamethods, if any) and frees all dynamic memory used by@@ -284,22 +288,18 @@ -- -- This is a wrapper function of -- <https://www.lua.org/manual/5.3/manual.html#lua_compare lua_compare>.-compare :: StackIndex -> StackIndex -> LuaRelation -> Lua Bool+compare :: StackIndex -> StackIndex -> RelationalOperator -> Lua Bool #if LUA_VERSION_NUMBER >= 502 compare idx1 idx2 relOp = fmap (/= 0) . throwOnError =<< do- liftLua $ \l ->- hslua_compare l- (fromStackIndex idx1)- (fromStackIndex idx2)- (fromLuaRelation relOp)+ liftLua $ \l -> hslua_compare l idx1 idx2 (fromRelationalOperator relOp) #else compare idx1 idx2 op = liftLua $ \l -> (/= 0) <$> case op of- LuaEQ -> lua_equal l (fromStackIndex idx1) (fromStackIndex idx2)- LuaLT -> lua_lessthan l (fromStackIndex idx1) (fromStackIndex idx2)- LuaLE -> (+) <$> lua_equal l (fromStackIndex idx1) (fromStackIndex idx2)- <*> lua_lessthan l (fromStackIndex idx1) (fromStackIndex idx2)+ EQ -> lua_equal l idx1 idx2+ LT -> lua_lessthan l idx1 idx2+ LE -> (+) <$> lua_equal l idx1 idx2+ <*> lua_lessthan l idx1 idx2 #endif -- | Concatenates the @n@ values at the top of the stack, pops them, and leaves@@ -311,8 +311,8 @@ -- -- This is a wrapper function of -- <https://www.lua.org/manual/5.3/manual.html#lua_concat lua_concat>.-concat :: Int -> Lua ()-concat n = void . throwOnError =<< liftLua (`hslua_concat` fromIntegral n)+concat :: NumArgs -> Lua ()+concat n = void . throwOnError =<< liftLua (`hslua_concat` n) -- | Copies the element at index @fromidx@ into the valid index @toidx@, -- replacing the value at that position. Values at other positions are not@@ -322,8 +322,7 @@ -- the lua manual. copy :: StackIndex -> StackIndex -> Lua () #if LUA_VERSION_NUMBER >= 503-copy fromidx toidx = liftLua $ \l ->- lua_copy l (fromStackIndex fromidx) (fromStackIndex toidx)+copy fromidx toidx = liftLua $ \l -> lua_copy l fromidx toidx #else copy fromidx toidx = do pushvalue fromidx@@ -344,6 +343,25 @@ createtable narr nrec = liftLua $ \l -> lua_createtable l (fromIntegral narr) (fromIntegral nrec) +-- | Loads and runs the given string.+--+-- Returns @'OK'@ on success, or an error if either loading of the string or+-- calling of the thunk failed.+dostring :: String -> Lua Status+dostring s = do+ loadRes <- loadstring s+ if loadRes == OK+ then pcall 0 multret Nothing+ else return loadRes++-- | Loads and runs the given file.+dofile :: FilePath -> Lua Status+dofile fp = do+ loadRes <- loadfile fp+ if loadRes == OK+ then pcall 0 multret Nothing+ else return loadRes+ -- TODO: implement dump -- | Returns @True@ if the two values in acceptable indices index1 and index2@@ -351,7 +369,7 @@ -- call metamethods). Otherwise returns False. Also returns False if any of the -- indices is non valid. Uses @'compare'@ internally. equal :: StackIndex -> StackIndex -> Lua Bool-equal index1 index2 = compare index1 index2 LuaEQ+equal index1 index2 = compare index1 index2 EQ -- | Controls the garbage collector. --@@ -397,7 +415,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_getfield lua_getfield>. getfield :: StackIndex -> String -> Lua () getfield i s = void . throwOnError =<< liftLua- (\l -> withCString s (hslua_getfield l (fromStackIndex i)))+ (\l -> withCString s (hslua_getfield l i)) -- | Pushes onto the stack the value of the global @name@. Returns the type of -- that value.@@ -416,7 +434,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_getmetatable lua_getmetatable>. getmetatable :: StackIndex -> Lua Bool getmetatable n = liftLua $ \l ->- fmap (/= 0) (lua_getmetatable l (fromStackIndex n))+ fmap (/= 0) (lua_getmetatable l n) -- | Pushes onto the stack the value @t[k]@, where @t@ is the value at the given -- index and @k@ is the value at the top of the stack.@@ -430,7 +448,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_gettable lua_gettable>. gettable :: StackIndex -> Lua () gettable n = void . throwOnError =<<- liftLua (\l -> hslua_gettable l (fromStackIndex n))+ liftLua (\l -> hslua_gettable l n) -- | Returns the index of the top element in the stack. Because indices start at -- 1, this result is equal to the number of elements in the stack (and so 0@@ -438,7 +456,7 @@ -- -- See also: <https://www.lua.org/manual/5.3/manual.html#lua_gettop lua_gettop>. gettop :: Lua StackIndex-gettop = liftLua $ fmap fromIntegral . lua_gettop+gettop = liftLua lua_gettop -- | Moves the top element into the given valid index, shifting up the elements -- above this index to open space. This function cannot be called with a@@ -448,9 +466,9 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_insert lua_insert>. insert :: StackIndex -> Lua () #if LUA_VERSION_NUMBER >= 503-insert index = liftLua $ \l -> lua_rotate l (fromStackIndex index) 1+insert index = liftLua $ \l -> lua_rotate l index 1 #else-insert index = liftLua $ \l -> lua_insert l (fromStackIndex index)+insert index = liftLua $ \l -> lua_insert l index #endif -- | Returns @True@ if the value at the given index is a boolean, and @False@@@ -459,7 +477,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isboolean lua_isboolean>. isboolean :: StackIndex -> Lua Bool-isboolean n = (== TBOOLEAN) <$> ltype n+isboolean n = (== TypeBoolean) <$> ltype n -- | Returns @True@ if the value at the given index is a C function, and @False@ -- otherwise.@@ -467,7 +485,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_iscfunction lua_iscfunction>. iscfunction :: StackIndex -> Lua Bool-iscfunction n = liftLua $ \l -> (/= 0) <$> lua_iscfunction l (fromStackIndex n)+iscfunction n = liftLua $ \l -> fromLuaBool <$> lua_iscfunction l n -- | Returns @True@ if the value at the given index is a function (either C or -- Lua), and @False@ otherwise.@@ -475,7 +493,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isfunction lua_isfunction>. isfunction :: StackIndex -> Lua Bool-isfunction n = (== TFUNCTION) <$> ltype n+isfunction n = (== TypeFunction) <$> ltype n -- | Returns @True@ if the value at the given index is a light userdata, and -- @False@ otherwise.@@ -484,7 +502,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_islightuserdata \ -- lua_islightuserdata>. islightuserdata :: StackIndex -> Lua Bool-islightuserdata n = (== TLIGHTUSERDATA) <$> ltype n+islightuserdata n = (== TypeLightUserdata) <$> ltype n -- | Returns @True@ if the value at the given index is @nil@, and @False@ -- otherwise.@@ -492,14 +510,14 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isnil lua_isnil>. isnil :: StackIndex -> Lua Bool-isnil n = (== TNIL) <$> ltype n+isnil n = (== TypeNil) <$> ltype n -- | Returns @True@ if the given index is not valid, and @False@ otherwise. -- -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isnone lua_isnone>. isnone :: StackIndex -> Lua Bool-isnone n = (== TNONE) <$> ltype n+isnone n = (== TypeNone) <$> ltype n -- | Returns @True@ if the given index is not valid or if the value at the given -- index is @nil@, and @False@ otherwise.@@ -507,7 +525,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isnoneornil lua_isnoneornil>. isnoneornil :: StackIndex -> Lua Bool-isnoneornil idx = (<= TNIL) <$> ltype idx+isnoneornil idx = (<= TypeNil) <$> ltype idx -- | Returns @True@ if the value at the given index is a number or a string -- convertible to a number, and @False@ otherwise.@@ -515,7 +533,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isnumber lua_isnumber>. isnumber :: StackIndex -> Lua Bool-isnumber n = liftLua $ \l -> (/= 0) <$> lua_isnumber l (fromStackIndex n)+isnumber n = liftLua $ \l -> fromLuaBool <$> lua_isnumber l n -- | Returns @True@ if the value at the given index is a string or a number -- (which is always convertible to a string), and @False@ otherwise.@@ -523,7 +541,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isstring lua_isstring>. isstring :: StackIndex -> Lua Bool-isstring n = liftLua $ \l -> (/= 0) <$> lua_isstring l (fromStackIndex n)+isstring n = liftLua $ \l -> fromLuaBool <$> lua_isstring l n -- | Returns @True@ if the value at the given index is a table, and @False@ -- otherwise.@@ -531,7 +549,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_istable lua_istable>. istable :: StackIndex -> Lua Bool-istable n = (== TTABLE) <$> ltype n+istable n = (== TypeTable) <$> ltype n -- | Returns @True@ if the value at the given index is a thread, and @False@ -- otherwise.@@ -539,7 +557,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isthread lua_isthread>. isthread :: StackIndex -> Lua Bool-isthread n = (== TTHREAD) <$> ltype n+isthread n = (== TypeThread) <$> ltype n -- | Returns @True@ if the value at the given index is a userdata (either full -- or light), and @False@ otherwise.@@ -547,7 +565,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_isuserdata lua_isuserdata>. isuserdata :: StackIndex -> Lua Bool-isuserdata n = liftLua $ \l -> (/= 0) <$> lua_isuserdata l (fromStackIndex n)+isuserdata n = liftLua $ \l -> fromLuaBool <$> lua_isuserdata l n -- | This is a convenience function to implement error propagation convention -- described in [Error handling in hslua](#g:1). hslua doesn't implement@@ -562,30 +580,28 @@ -- | Tests whether the object under the first index is smaller than that under -- the second. Uses @'compare'@ internally. lessthan :: StackIndex -> StackIndex -> Lua Bool-lessthan index1 index2 = compare index1 index2 LuaLT+lessthan index1 index2 = compare index1 index2 LT -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_loadfile luaL_loadfile>.-loadfile :: String -> Lua Int+loadfile :: String -> Lua Status #if LUA_VERSION_NUMBER >= 502 loadfile f = liftLua $ \l -> withCString f $ \fPtr ->- fromIntegral <$> luaL_loadfilex l fPtr nullPtr+ toStatus <$> luaL_loadfilex l fPtr nullPtr #else loadfile f = liftLua $ \l -> withCString f $ \fPtr ->- fromIntegral <$> luaL_loadfile l fPtr+ toStatus <$> luaL_loadfile l fPtr #endif -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_loadstring luaL_loadstring>.-loadstring :: String -> Lua LuaStatus+loadstring :: String -> Lua Status loadstring str = liftLua $ \l ->- withCString str $ \strPtr ->- toLuaStatus <$> luaL_loadstring l strPtr+ withCString str (fmap toStatus . luaL_loadstring l) -- | See <https://www.lua.org/manual/5.3/manual.html#lua_type lua_type>.-ltype :: StackIndex -> Lua LTYPE-ltype idx = toLuaType <$>- liftLua (flip lua_type $ fromStackIndex idx)+ltype :: StackIndex -> Lua Type+ltype idx = toType <$> liftLua (flip lua_type idx) -- | If the registry already has the key tname, returns @False@. Otherwise, -- creates a new table to be used as a metatable for userdata, adds to this new@@ -600,7 +616,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#luaL_newmetatable luaL_newmetatable>. newmetatable :: String -> Lua Bool newmetatable tname = liftLua $ \l ->- (/= 0) <$> withCString tname (luaL_newmetatable l)+ fromLuaBool <$> withCString tname (luaL_newmetatable l) -- | Creates a new Lua state. It calls @'lua_newstate'@ with an allocator based -- on the standard C @realloc@ function and then sets a panic function (see@@ -643,7 +659,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_next lua_next>. next :: StackIndex -> Lua Bool next idx = fmap (/= 0) . throwOnError =<<- liftLua (\l -> hslua_next l (fromStackIndex idx))+ liftLua (\l -> hslua_next l idx) {-# DEPRECATED objlen "Use rawlen instead." #-} -- | Obsolete alias for @'rawlen'@.@@ -732,23 +748,13 @@ -- after the return of @'pcall'@, since by then the stack has unwound. -- -- See <https://www.lua.org/manual/5.3/manual.html#lua_pcall lua_pcall>.-pcall :: NumArgs -> NumResults -> Maybe StackIndex -> Lua LuaStatus+pcall :: NumArgs -> NumResults -> Maybe StackIndex -> Lua Status #if LUA_VERSION_NUMBER >= 502 pcall nargs nresults msgh = liftLua $ \l ->- toLuaStatus <$>- lua_pcallk l- (fromNumArgs nargs)- (fromNumResults nresults)- (maybe 0 fromStackIndex msgh)- 0- nullPtr+ toStatus <$> lua_pcallk l nargs nresults (fromMaybe 0 msgh) 0 nullPtr #else pcall nargs nresults msgh = liftLua $ \l ->- toLuaStatus <$>- lua_pcall l- (fromNumArgs nargs)- (fromNumResults nresults)- (maybe 0 fromStackIndex msgh)+ toStatus <$> lua_pcall l nargs nresults (fromMaybe 0 msgh) #endif -- | Pops @n@ elements from the stack.@@ -762,7 +768,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_pushboolean lua_pushboolean>. pushboolean :: Bool -> Lua ()-pushboolean b = liftLua $ \l -> lua_pushboolean l (fromIntegral (fromEnum b))+pushboolean b = liftLua $ \l -> lua_pushboolean l (toLuaBool b) -- | Pushes a new C closure onto the stack. --@@ -849,7 +855,7 @@ -- -- See <https://www.lua.org/manual/5.3/manual.html#lua_pushvalue lua_pushvalue>. pushvalue :: StackIndex -> Lua ()-pushvalue n = liftLua $ \l -> lua_pushvalue l (fromStackIndex n)+pushvalue n = liftLua $ \l -> lua_pushvalue l n -- | Returns @True@ if the two values in indices @idx1@ and @idx2@ are -- primitively equal (that is, without calling the @__eq@ metamethod). Otherwise@@ -859,14 +865,14 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_rawequal lua_rawequal>. rawequal :: StackIndex -> StackIndex -> Lua Bool rawequal idx1 idx2 = liftLua $ \l ->- (/= 0) <$> lua_rawequal l (fromStackIndex idx1) (fromStackIndex idx2)+ fromLuaBool <$> lua_rawequal l idx1 idx2 -- | Similar to @'gettable'@, but does a raw access (i.e., without metamethods). -- -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_rawget lua_rawget>. rawget :: StackIndex -> Lua ()-rawget n = liftLua $ \l -> lua_rawget l (fromStackIndex n)+rawget n = liftLua $ \l -> lua_rawget l n -- | Pushes onto the stack the value @t[n]@, where @t@ is the table at the given -- index. The access is raw, that is, it does not invoke the @__index@@@ -875,7 +881,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_rawgeti lua_rawgeti>. rawgeti :: StackIndex -> Int -> Lua ()-rawgeti k m = liftLua $ \l -> lua_rawgeti l (fromStackIndex k) (fromIntegral m)+rawgeti k m = liftLua $ \l -> lua_rawgeti l k (fromIntegral m) -- | 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@@ -886,9 +892,9 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_rawlen lua_rawlen>. rawlen :: StackIndex -> Lua Int #if LUA_VERSION_NUMBER >= 502-rawlen idx = liftLua $ \l -> fromIntegral <$> lua_rawlen l (fromStackIndex idx)+rawlen idx = liftLua $ \l -> fromIntegral <$> lua_rawlen l idx #else-rawlen idx = liftLua $ \l -> fromIntegral <$> lua_objlen l (fromStackIndex idx)+rawlen idx = liftLua $ \l -> fromIntegral <$> lua_objlen l idx #endif -- | Similar to @'settable'@, but does a raw assignment (i.e., without@@ -897,7 +903,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_rawset lua_rawset>. rawset :: StackIndex -> Lua ()-rawset n = liftLua $ \l -> lua_rawset l (fromStackIndex n)+rawset n = liftLua $ \l -> lua_rawset l n -- | Does the equivalent of @t[i] = v@, where @t@ is the table at the given -- index and @v@ is the value at the top of the stack.@@ -908,11 +914,11 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_rawseti lua_rawseti>. rawseti :: StackIndex -> Int -> Lua ()-rawseti k m = liftLua $ \l -> lua_rawseti l (fromStackIndex k) (fromIntegral m)+rawseti k m = liftLua $ \l -> lua_rawseti l k (fromIntegral m) -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_ref luaL_ref>. ref :: StackIndex -> Lua Int-ref t = liftLua $ \l -> fromIntegral <$> luaL_ref l (fromStackIndex t)+ref t = liftLua $ \l -> fromIntegral <$> luaL_ref l t -- | Sets the C function @f@ as the new value of global @name@. --@@ -929,9 +935,9 @@ -- See <https://www.lua.org/manual/5.3/manual.html#lua_remove lua_remove>. remove :: StackIndex -> Lua () #if LUA_VERSION_NUMBER >= 503-remove n = liftLua (\l -> lua_rotate l (fromStackIndex n) (-1)) *> pop 1+remove n = liftLua (\l -> lua_rotate l n (-1)) *> pop 1 #else-remove n = liftLua $ \l -> lua_remove l (fromStackIndex n)+remove n = liftLua $ \l -> lua_remove l n #endif -- | Moves the top element into the given valid index without shifting any@@ -941,9 +947,9 @@ -- See <https://www.lua.org/manual/5.3/manual.html#lua_replace lua_replace>. replace :: StackIndex -> Lua () #if LUA_VERSION_NUMBER >= 503-replace n = liftLua (\l -> lua_copy l (-1) (fromStackIndex n)) *> pop 1+replace n = liftLua (\l -> lua_copy l (-1) n) *> pop 1 #else-replace n = liftLua $ \l -> lua_replace l (fromStackIndex n)+replace n = liftLua $ \l -> lua_replace l n #endif -- | Does the equivalent to @t[k] = v@, where @t@ is the value at the given@@ -958,7 +964,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_setfield lua_setfield>. setfield :: StackIndex -> String -> Lua () setfield i s = void . throwOnError =<<- liftLua (\l -> withCString s (hslua_setfield l (fromStackIndex i)))+ liftLua (\l -> withCString s (hslua_setfield l i)) -- | Pops a value from the stack and sets it as the new value of global @name@. --@@ -975,7 +981,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_setmetatable \ -- lua_setmetatable>. setmetatable :: StackIndex -> Lua ()-setmetatable idx = liftLua $ \l -> lua_setmetatable l (fromStackIndex idx)+setmetatable idx = liftLua $ \l -> lua_setmetatable l idx -- | Does the equivalent to @t[k] = v@, where @t@ is the value at the given -- index, @v@ is the value at the top of the stack, and @k@ is the value just@@ -990,7 +996,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_settable lua_settable>. settable :: StackIndex -> Lua () settable index = void . throwOnError =<<- liftLua (\l -> hslua_settable l (fromStackIndex index))+ liftLua (\l -> hslua_settable l index) -- | Accepts any index, or 0, and sets the stack top to this index. If the new -- top is larger than the old one, then the new elements are filled with nil. If@@ -999,21 +1005,21 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_settop lua_settop>. settop :: StackIndex -> Lua ()-settop = liftLua1 lua_settop . fromStackIndex+settop = liftLua1 lua_settop -- | Returns the status of this Lua thread. ----- The status can be @'LuaOK'@ for a normal thread, an error value if the thread--- finished the execution of a @'lua_resume'@ with an error, or @'LuaYield'@ if+-- The status can be @'OK'@ for a normal thread, an error value if the thread+-- finished the execution of a @'lua_resume'@ with an error, or @'Yield'@ if -- the thread is suspended. ----- You can only call functions in threads with status @'LuaOK'@. You can resume--- threads with status @'LuaOK'@ (to start a new coroutine) or @'LuaYield'@ (to+-- You can only call functions in threads with status @'OK'@. You can resume+-- threads with status @'OK'@ (to start a new coroutine) or @'Yield'@ (to -- resume a coroutine). -- -- See also: <https://www.lua.org/manual/5.3/manual.html#lua_status lua_status>.-status :: Lua LuaStatus-status = liftLua $ fmap toLuaStatus . lua_status+status :: Lua Status+status = liftLua $ fmap toStatus . lua_status {-# DEPRECATED strlen "Use rawlen instead." #-} -- | Compatibility alias for rawlen@@ -1028,7 +1034,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_toboolean lua_toboolean>. toboolean :: StackIndex -> Lua Bool-toboolean n = liftLua $ \l -> (/= 0) <$> lua_toboolean l (fromStackIndex n)+toboolean n = liftLua $ \l -> (/= 0) <$> lua_toboolean l n -- | Converts a value at the given index to a C function. That value must be a C -- function; otherwise, returns NULL.@@ -1036,7 +1042,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_tocfunction lua_tocfunction>. tocfunction :: StackIndex -> Lua CFunction-tocfunction n = liftLua $ \l -> lua_tocfunction l (fromStackIndex n)+tocfunction n = liftLua $ \l -> lua_tocfunction l n -- | 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@@ -1050,11 +1056,28 @@ -- <https://www.lua.org/manual/5.3/manual.html#lua_tointeger lua_tointeger>. tointeger :: StackIndex -> Lua LuaInteger #if LUA_VERSION_NUMBER >= 502-tointeger n = liftLua $ \l -> lua_tointegerx l (fromStackIndex n) 0+tointeger n = liftLua $ \l -> lua_tointegerx l n nullPtr #else-tointeger n = liftLua $ \l -> lua_tointeger l (fromStackIndex n)+tointeger n = liftLua $ \l -> lua_tointeger l n #endif +-- | Like @'tointeger'@, but returns @Nothing@ if the conversion failed+tointegerx :: StackIndex -> Lua (Maybe LuaInteger)+#if LUA_VERSION_NUMBER >= 502+tointegerx n = liftLua $ \l -> alloca $ \bptr -> do+ res <- lua_tointegerx l n bptr+ isNum <- fromLuaBool <$> F.peek bptr+ if isNum+ then return $ Just res+ else return $ Nothing+#else+tointegerx n = do+ isNum <- isnumber n+ if isNum+ then Just <$> tointeger n+ else return Nothing+#endif+ -- | Converts the Lua value at the given index to the C type lua_Number. The Lua -- value must be a number or a string convertible to a number; otherwise, -- @tonumber@ returns 0.@@ -1062,11 +1085,28 @@ -- See <https://www.lua.org/manual/5.3/manual.html#lua_tonumber lua_tonumber>. tonumber :: StackIndex -> Lua LuaNumber #if LUA_VERSION_NUMBER >= 502-tonumber n = liftLua $ \l -> lua_tonumberx l (fromStackIndex n) 0+tonumber n = liftLua $ \l -> lua_tonumberx l n nullPtr #else-tonumber n = liftLua $ \l -> lua_tonumber l (fromStackIndex n)+tonumber n = liftLua $ \l -> lua_tonumber l n #endif +-- | Like @'tonumber'@, but returns @Nothing@ if the conversion failed+tonumberx :: StackIndex -> Lua (Maybe LuaNumber)+#if LUA_VERSION_NUMBER >= 502+tonumberx n = liftLua $ \l -> alloca $ \bptr -> do+ res <- lua_tonumberx l n bptr+ isNum <- fromLuaBool <$> F.peek bptr+ if isNum+ then return $ Just res+ else return $ Nothing+#else+tonumberx n = do+ isNum <- isnumber n+ if isNum+ then Just <$> tonumber n+ else return Nothing+#endif+ -- | 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 NULL. Different objects will give different pointers.@@ -1077,14 +1117,14 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_topointer lua_topointer>. topointer :: StackIndex -> Lua (Ptr ())-topointer n = liftLua $ \l -> lua_topointer l (fromStackIndex n)+topointer n = liftLua $ \l -> lua_topointer l n -- | See <https://www.lua.org/manual/5.3/manual.html#lua_tostring lua_tostring>. tostring :: StackIndex -> Lua B.ByteString tostring n = liftLua $ \l -> alloca $ \lenPtr -> do- cstr <- lua_tolstring l (fromStackIndex n) lenPtr- cstrLen <- F.peek lenPtr- B.packCStringLen (cstr, fromIntegral cstrLen)+ cstr <- lua_tolstring l n lenPtr+ cstrLen <- F.peek lenPtr+ B.packCStringLen (cstr, fromIntegral cstrLen) -- | Converts the value at the given index to a Lua thread (represented as -- lua_State*). This value must be a thread; otherwise, the function returns@@ -1093,7 +1133,7 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_tothread lua_tothread>. tothread :: StackIndex -> Lua LuaState-tothread n = liftLua $ \l -> lua_tothread l (fromStackIndex n)+tothread n = liftLua $ \l -> lua_tothread l n -- | 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,@@ -1102,16 +1142,16 @@ -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_touserdata lua_touserdata>. touserdata :: StackIndex -> Lua (Ptr a)-touserdata n = liftLua $ \l -> lua_touserdata l (fromStackIndex n)+touserdata n = liftLua $ \l -> lua_touserdata l n -- | Returns the name of the type encoded by the value @tp@, which must be one -- the values returned by @'ltype'@. -- -- See also: -- <https://www.lua.org/manual/5.3/manual.html#lua_typename lua_typename>.-typename :: LTYPE -> Lua String+typename :: Type -> Lua String typename tp = liftLua $ \l ->- lua_typename l (fromLuaType tp) >>= peekCString+ lua_typename l (fromType tp) >>= peekCString -- | Releases reference @'ref'@ from the table at index @idx@ (see @'ref'@). The -- entry is removed from the table, so that the referred object can be@@ -1121,7 +1161,7 @@ -- <https://www.lua.org/manual/5.3/manual.html#luaL_unref luaL_unref>. unref :: StackIndex -> Int -> Lua () unref idx r = liftLua $ \l ->- luaL_unref l (fromStackIndex idx) (fromIntegral r)+ luaL_unref l idx (fromIntegral r) -- | Returns the pseudo-index that represents the @i@-th upvalue of the running -- function (see <https://www.lua.org/manual/5.3/manual.html#4.4 §4.4> of the
src/Foreign/Lua/Api/RawBindings.hsc view
@@ -42,6 +42,7 @@ import Foreign.Ptr #include "lua.h"+#include "safer-api.h" -- TODO: lua_getallocf, lua_setallocf -- TODO: Debugger functions@@ -54,21 +55,13 @@ -------------------------------------------------------------------------------- -- * State manipulation --- | See <https://www.lua.org/manual/5.3/manual.html#lua_newstate lua_newstate>-foreign import ccall unsafe "lua.h lua_newstate"- lua_newstate :: FunPtr LuaAlloc -> Ptr () -> IO LuaState+-- lua_newstate is currently not supported. -- | See <https://www.lua.org/manual/5.3/manual.html#lua_close lua_close> foreign import ccall "lua.h lua_close" lua_close :: LuaState -> IO () --- | See <https://www.lua.org/manual/5.3/manual.html#lua_newthread lua_newthread>-foreign import ccall unsafe "lua.h lua_newthread"- lua_newthread :: LuaState -> IO LuaState---- | See <https://www.lua.org/manual/5.3/manual.html#lua_atpanic lua_atpanic>-foreign import ccall "lua.h lua_atpanic"- lua_atpanic :: LuaState -> CFunction -> IO CFunction+-- lua_newthread is currently not supported. --------------------------------------------------------------------------------@@ -76,45 +69,43 @@ -- | See <https://www.lua.org/manual/5.3/manual.html#lua_gettop lua_gettop> foreign import ccall unsafe "lua.h lua_gettop"- lua_gettop :: LuaState -> IO CInt+ lua_gettop :: LuaState -> IO StackIndex -- | See <https://www.lua.org/manual/5.3/manual.html#lua_settop lua_settop> foreign import ccall unsafe "lua.h lua_settop"- lua_settop :: LuaState -> CInt -> IO ()+ lua_settop :: LuaState -> StackIndex -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_pushvalue lua_pushvalue> foreign import ccall unsafe "lua.h lua_pushvalue"- lua_pushvalue :: LuaState -> CInt -> IO ()+ lua_pushvalue :: LuaState -> StackIndex -> IO () #if LUA_VERSION_NUMBER >= 503 -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rotate lua_rotate> foreign import ccall unsafe "lua.h lua_rotate"- lua_rotate :: LuaState -> CInt -> CInt -> IO ()+ lua_rotate :: LuaState -> StackIndex -> CInt -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_copy lua_copy> foreign import ccall unsafe "lua.h lua_copy"- lua_copy :: LuaState -> CInt -> CInt -> IO ()+ lua_copy :: LuaState -> StackIndex -> StackIndex -> IO () #else -- | See <https://www.lua.org/manual/5.2/manual.html#lua_remove lua_remove> foreign import ccall unsafe "lua.h lua_remove"- lua_remove :: LuaState -> CInt -> IO ()+ lua_remove :: LuaState -> StackIndex -> IO () -- | See <https://www.lua.org/manual/5.2/manual.html#lua_insert lua_insert> foreign import ccall unsafe "lua.h lua_insert"- lua_insert :: LuaState -> CInt -> IO ()+ lua_insert :: LuaState -> StackIndex -> IO () -- | See <https://www.lua.org/manual/5.2/manual.html#lua_replace lua_replace> foreign import ccall unsafe "lua.h lua_replace"- lua_replace :: LuaState -> CInt -> IO ()+ lua_replace :: LuaState -> StackIndex -> IO () #endif -- | See <https://www.lua.org/manual/5.3/manual.html#lua_checkstack lua_checkstack> foreign import ccall unsafe "lua.h lua_checkstack"- lua_checkstack :: LuaState -> CInt -> IO CInt+ lua_checkstack :: LuaState -> StackIndex -> IO LuaBool --- | See <https://www.lua.org/manual/5.3/manual.html#lua_xmove lua_xmove>-foreign import ccall unsafe "lua.h lua_xmove"- lua_xmove :: LuaState -> LuaState -> CInt -> IO ()+-- lua_xmove is currently not supported. --------------------------------------------------------------------------------@@ -122,90 +113,93 @@ -- | See <https://www.lua.org/manual/5.3/manual.html#lua_isnumber lua_isnumber> foreign import ccall unsafe "lua.h lua_isnumber"- lua_isnumber :: LuaState -> CInt -> IO CInt+ lua_isnumber :: LuaState -> StackIndex -> IO LuaBool -- | See <https://www.lua.org/manual/5.3/manual.html#lua_isstring lua_isstring> foreign import ccall unsafe "lua.h lua_isstring"- lua_isstring :: LuaState -> CInt -> IO CInt+ lua_isstring :: LuaState -> StackIndex -> IO LuaBool -- | See <https://www.lua.org/manual/5.3/manual.html#lua_iscfunction lua_iscfunction> foreign import ccall unsafe "lua.h lua_iscfunction"- lua_iscfunction :: LuaState -> CInt -> IO CInt+ lua_iscfunction :: LuaState -> StackIndex -> IO LuaBool -- | See <https://www.lua.org/manual/5.3/manual.html#lua_isuserdata lua_isuserdata> foreign import ccall unsafe "lua.h lua_isuserdata"- lua_isuserdata :: LuaState -> CInt -> IO CInt+ lua_isuserdata :: LuaState -> StackIndex -> IO LuaBool -- | See <https://www.lua.org/manual/5.3/manual.html#lua_type lua_type> foreign import ccall unsafe "lua.h lua_type"- lua_type :: LuaState -> CInt -> IO CInt+ lua_type :: LuaState -> StackIndex -> IO TypeCode -- | See <https://www.lua.org/manual/5.3/manual.html#lua_typename lua_typename> foreign import ccall unsafe "lua.h lua_typename"- lua_typename :: LuaState -> CInt -> IO (Ptr CChar)+ lua_typename :: LuaState -> TypeCode -> IO (Ptr CChar) -#if LUA_VERSION_NUMBER >= 502--- | See <https://www.lua.org/manual/5.3/manual.html#lua_compare lua_compare>-foreign import ccall "lua.h lua_compare"- lua_compare :: LuaState -> CInt -> CInt -> CInt -> IO CInt+-- lua_compare is unsafe (might cause a longjmp), use hslua_compare instead.+#if LUA_VERSION_NUM >= 502+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_compare \+-- @lua_compare@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_compare"+ hslua_compare :: LuaState -> StackIndex -> StackIndex -> CInt+ -> IO (Failable LuaBool) #else -- | See <https://www.lua.org/manual/5.1/manual.html#lua_equal lua_equal> foreign import ccall "lua.h lua_equal"- lua_equal :: LuaState -> CInt -> CInt -> IO CInt+ lua_equal :: LuaState -> StackIndex -> StackIndex -> IO CInt -- | See <https://www.lua.org/manual/5.1/manual.html#lua_lessthan lua_lessthan> foreign import ccall "lua.h lua_lessthan"- lua_lessthan :: LuaState -> CInt -> CInt -> IO CInt+ lua_lessthan :: LuaState -> StackIndex -> StackIndex -> IO CInt #endif -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rawequal lua_rawequal> foreign import ccall unsafe "lua.h lua_rawequal"- lua_rawequal :: LuaState -> CInt -> CInt -> IO CInt+ lua_rawequal :: LuaState -> StackIndex -> StackIndex -> IO LuaBool -- -- Type coercion -- -- | See <https://www.lua.org/manual/5.3/manual.html#lua_toboolean lua_toboolean> foreign import ccall unsafe "lua.h lua_toboolean"- lua_toboolean :: LuaState -> CInt -> IO CInt+ lua_toboolean :: LuaState -> StackIndex -> IO StackIndex -- | See <https://www.lua.org/manual/5.3/manual.html#lua_tocfunction lua_tocfunction> foreign import ccall unsafe "lua.h lua_tocfunction"- lua_tocfunction :: LuaState -> CInt -> IO CFunction+ lua_tocfunction :: LuaState -> StackIndex -> IO CFunction #if LUA_VERSION_NUMBER >= 502 -- | See <https://www.lua.org/manual/5.3/manual.html#lua_tointegerx lua_tointegerx> foreign import ccall unsafe "lua.h lua_tointegerx"- lua_tointegerx :: LuaState -> CInt -> CInt -> IO LuaInteger+ lua_tointegerx :: LuaState -> StackIndex -> Ptr LuaBool -> IO LuaInteger -- | See <https://www.lua.org/manual/5.3/manual.html#lua_tonumberx lua_tonumberx> foreign import ccall unsafe "lua.h lua_tonumberx"- lua_tonumberx :: LuaState -> CInt -> CInt -> IO LuaNumber+ lua_tonumberx :: LuaState -> StackIndex -> Ptr LuaBool -> IO LuaNumber #else -- | See <https://www.lua.org/manual/5.1/manual.html#lua_tointeger lua_tointeger> foreign import ccall unsafe "lua.h lua_tointeger"- lua_tointeger :: LuaState -> CInt -> IO LuaInteger+ lua_tointeger :: LuaState -> StackIndex -> IO LuaInteger -- | See <https://www.lua.org/manual/5.1/manual.html#lua_tonumber lua_tonumber> foreign import ccall unsafe "lua.h lua_tonumber"- lua_tonumber :: LuaState -> CInt -> IO LuaNumber+ lua_tonumber :: LuaState -> StackIndex -> IO LuaNumber #endif -- | See <https://www.lua.org/manual/5.3/manual.html#lua_tolstring lua_tolstring> foreign import ccall unsafe "lua.h lua_tolstring"- lua_tolstring :: LuaState -> CInt -> Ptr CSize -> IO (Ptr CChar)+ lua_tolstring :: LuaState -> StackIndex -> Ptr CSize -> IO (Ptr CChar) -- | See <https://www.lua.org/manual/5.3/manual.html#lua_topointer lua_topointer> foreign import ccall unsafe "lua.h lua_topointer"- lua_topointer :: LuaState -> CInt -> IO (Ptr ())+ lua_topointer :: LuaState -> StackIndex -> IO (Ptr ()) -- | See <https://www.lua.org/manual/5.3/manual.html#lua_tothread lua_tothread> foreign import ccall unsafe "lua.h lua_tothread"- lua_tothread :: LuaState -> CInt -> IO LuaState+ lua_tothread :: LuaState -> StackIndex -> IO LuaState -- | See <https://www.lua.org/manual/5.3/manual.html#lua_touserdata lua_touserdata> foreign import ccall unsafe "lua.h lua_touserdata"- lua_touserdata :: LuaState -> CInt -> IO (Ptr a)+ lua_touserdata :: LuaState -> StackIndex -> IO (Ptr a) --@@ -215,11 +209,11 @@ #if LUA_VERSION_NUMBER >= 502 -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rawlen lua_rawlen> foreign import ccall unsafe "lua.h lua_rawlen"- lua_rawlen :: LuaState -> CInt -> IO CSize+ lua_rawlen :: LuaState -> StackIndex -> IO CSize #else -- | See <https://www.lua.org/manual/5.1/manual.html#lua_objlen lua_objlen> foreign import ccall unsafe "lua.h lua_objlen"- lua_objlen :: LuaState -> CInt -> IO CSize+ lua_objlen :: LuaState -> StackIndex -> IO CSize #endif @@ -242,17 +236,16 @@ foreign import ccall unsafe "lua.h lua_pushlstring" lua_pushlstring :: LuaState -> Ptr CChar -> CSize -> IO () --- | See <https://www.lua.org/manual/5.3/manual.html#lua_pushstring lua_pushstring>-foreign import ccall unsafe "lua.h lua_pushstring"- lua_pushstring :: LuaState -> Ptr CChar -> IO ()+-- lua_pushstring is currently not supported. It's difficult to use in a haskell+-- context. -- | See <https://www.lua.org/manual/5.3/manual.html#lua_pushcclosure lua_pushcclosure> foreign import ccall unsafe "lua.h lua_pushcclosure"- lua_pushcclosure :: LuaState -> CFunction -> CInt -> IO ()+ lua_pushcclosure :: LuaState -> CFunction -> NumArgs -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_pushboolean lua_pushboolean> foreign import ccall unsafe "lua.h lua_pushboolean"- lua_pushboolean :: LuaState -> CInt -> IO ()+ lua_pushboolean :: LuaState -> LuaBool -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_pushlightuserdata lua_pushlightuserdata> foreign import ccall unsafe "lua.h lua_pushlightuserdata"@@ -266,27 +259,28 @@ -------------------------------------------------------------------------------- -- * Get functions -#if LUA_VERSION_NUMBER >= 503--- | See <https://www.lua.org/manual/5.3/manual.html#lua_gettable lua_gettable>-foreign import ccall "lua.h lua_gettable"- lua_gettable :: LuaState -> CInt -> IO CInt-#else--- | See <https://www.lua.org/manual/5.2/manual.html#lua_gettable lua_gettable>-foreign import ccall "lua.h lua_gettable"- lua_gettable :: LuaState -> CInt -> IO ()-#endif+-- lua_gettable is unsafe, use hslua_gettable instead.+-- lua_getfield is unsafe, use hslua_getfield instead.+-- lua_getglobal is unsafe, use hslua_getglobal instead.+-- lua_getfenv (5.1 only) is not supported. --- | See <https://www.lua.org/manual/5.3/manual.html#lua_getfield lua_getfield>-foreign import ccall "lua.h lua_getfield"- lua_getfield :: LuaState -> CInt -> Ptr CChar -> IO ()+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_gettable \+-- @lua_gettable@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_gettable"+ hslua_gettable :: LuaState -> StackIndex -> IO CInt +-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_getfield \+-- @lua_getfield@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_getfield"+ hslua_getfield :: LuaState -> StackIndex -> Ptr CChar -> IO CInt+ -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rawget lua_rawget> foreign import ccall unsafe "lua.h lua_rawget"- lua_rawget :: LuaState -> CInt -> IO ()+ lua_rawget :: LuaState -> StackIndex -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rawgeti lua_rawgeti> foreign import ccall unsafe "lua.h lua_rawgeti"- lua_rawgeti :: LuaState -> CInt -> CInt -> IO ()+ lua_rawgeti :: LuaState -> StackIndex -> CInt -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_createtable lua_createtable> foreign import ccall unsafe "lua.h lua_createtable"@@ -298,122 +292,81 @@ -- | See <https://www.lua.org/manual/5.3/manual.html#lua_getmetatable lua_getmetatable> foreign import ccall unsafe "lua.h lua_getmetatable"- lua_getmetatable :: LuaState -> CInt -> IO CInt+ lua_getmetatable :: LuaState -> StackIndex -> IO CInt -#if LUA_VERSION_NUMBER < 502--- | See <https://www.lua.org/manual/5.1/manual.html#lua_getfenv lua_getfenv>-foreign import ccall "lua.h lua_getfenv"- lua_getfenv :: LuaState -> CInt -> IO ()-#endif+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_getglobal \+-- @lua_getglobal@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_getglobal"+ hslua_getglobal :: LuaState -> Ptr CChar -> IO CInt -#if LUA_VERSION_NUMBER >= 502--- | See <https://www.lua.org/manual/5.3/manual.html#lua_getglobal lua_getglobal>-foreign import ccall "lua.h lua_getglobal"- lua_getglobal :: LuaState -> Ptr CChar -> IO ()-#endif -------------------------------------------------------------------------------- -- * Set functions --- | See <https://www.lua.org/manual/5.3/manual.html#lua_settable lua_settable>-foreign import ccall "lua.h lua_settable"- lua_settable :: LuaState -> CInt -> IO ()+-- lua_settable is unsafe, use hslua_settable instead.+-- lua_setfield is unsafe, use hslua_setfield instead.+-- lua_setglobal is unsafe, use hslua_setglobal instead.+-- lua_setfenv (5.1 only) is not supported. --- | See <https://www.lua.org/manual/5.3/manual.html#lua_setfield lua_setfield>-foreign import ccall "lua.h lua_setfield"- lua_setfield :: LuaState -> CInt -> Ptr CChar -> IO ()+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_settable \+-- @lua_settable@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_settable"+ hslua_settable :: LuaState -> StackIndex -> IO CInt +-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_setfield \+-- @lua_setfield@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_setfield"+ hslua_setfield :: LuaState -> StackIndex -> Ptr CChar -> IO CInt+ -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rawset lua_rawset> foreign import ccall unsafe "lua.h lua_rawset"- lua_rawset :: LuaState -> CInt -> IO ()+ lua_rawset :: LuaState -> StackIndex -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_rawseti lua_rawseti> foreign import ccall unsafe "lua.h lua_rawseti"- lua_rawseti :: LuaState -> CInt -> CInt -> IO ()+ lua_rawseti :: LuaState -> StackIndex -> CInt -> IO () -- | See <https://www.lua.org/manual/5.3/manual.html#lua_setmetatable lua_setmetatable> foreign import ccall unsafe "lua.h lua_setmetatable"- lua_setmetatable :: LuaState -> CInt -> IO ()+ lua_setmetatable :: LuaState -> StackIndex -> IO () -#if LUA_VERSION_NUMBER < 502--- | See <https://www.lua.org/manual/5.1/manual.html#lua_setfenv lua_setfenv>-foreign import ccall "lua.h lua_setfenv"- lua_setfenv :: LuaState -> CInt -> IO CInt-#endif+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_setglobal \+-- @lua_setglobal@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_setglobal"+ hslua_setglobal :: LuaState -> Ptr CChar -> IO CInt -#if LUA_VERSION_NUMBER >= 502--- | See <https://www.lua.org/manual/5.3/manual.html#lua_setglobal lua_setglobal>-foreign import ccall "lua.h lua_setglobal"- lua_setglobal :: LuaState -> Ptr CChar -> IO ()-#endif -------------------------------------------------------------------------------- -- * 'load' and 'call' functions (load and run Lua code) #if LUA_VERSION_NUMBER >= 502--- | See <https://www.lua.org/manual/5.3/manual.html#lua_callk lua_callk>-foreign import ccall "lua.h lua_callk"- lua_callk :: LuaState -> CInt -> CInt -> CInt -> Ptr () -> IO ()-#else--- | See <https://www.lua.org/manual/5.1/manual.html#lua_call lua_call>-foreign import ccall "lua.h lua_call"- lua_call :: LuaState -> CInt -> CInt -> IO ()-#endif--#if LUA_VERSION_NUMBER >= 502 -- | See <https://www.lua.org/manual/5.3/manual.html#lua_pcallk lua_pcallk> foreign import ccall "lua.h lua_pcallk"- lua_pcallk :: LuaState -> CInt -> CInt -> CInt -> CInt -> Ptr () -> IO CInt+ lua_pcallk :: LuaState -> NumArgs -> NumResults -> StackIndex+ -> CInt -> Ptr () -> IO StatusCode #else -- | See <https://www.lua.org/manual/5.1/manual.html#lua_pcall lua_pcall> foreign import ccall "lua.h lua_pcall"- lua_pcall :: LuaState -> CInt -> CInt -> CInt -> IO CInt-#endif--#if LUA_VERSION_NUMBER < 502--- | See <https://www.lua.org/manual/5.1/manual.html#lua_cpcall lua_cpcall>-foreign import ccall "lua.h lua_cpcall"- lua_cpcall :: LuaState -> CFunction -> Ptr a -> IO CInt+ lua_pcall :: LuaState -> NumArgs -> NumResults -> StackIndex+ -> IO StatusCode #endif --- | See <https://www.lua.org/manual/5.3/manual.html#lua_load lua_load>-foreign import ccall "lua.h lua_load"- lua_load :: LuaState -> FunPtr LuaReader -> Ptr () -> Ptr CChar -> IO CInt---- | See <https://www.lua.org/manual/5.3/manual.html#lua_dump lua_dump>-foreign import ccall "lua.h lua_dump"- lua_dump :: LuaState -> FunPtr LuaWriter -> Ptr () -> IO ()+-- currently unsupported:+-- lua_load+-- lua_dump ---------------------------------------------------------------------------------+------------------------------------------------------------------------------ -- * Coroutine functions -#if LUA_VERSION_NUMBER >= 502--- | See <https://www.lua.org/manual/5.3/manual.html#lua_yieldk lua_yieldk>-foreign import ccall "lua.h lua_yieldk"- lua_yieldk :: LuaState -> CInt -> CInt -> Ptr () -> IO CInt-#else--- | See <https://www.lua.org/manual/5.1/manual.html#lua_yield lua_yield>-foreign import ccall "lua.h lua_yield"- lua_yield :: LuaState -> CInt -> IO CInt-#endif--#if LUA_VERSION_NUMBER >= 502--- | See <https://www.lua.org/manual/5.3/manual.html#lua_resume lua_resume>-foreign import ccall "lua.h lua_resume"- lua_resume :: LuaState -> CInt -> CInt -> IO CInt-#else--- | See <https://www.lua.org/manual/5.1/manual.html#lua_resume lua_resume>-foreign import ccall "lua.h lua_resume"- lua_resume :: LuaState -> CInt -> IO CInt-#endif+-- lua_yield / lua_yieldk and lua_resume are currently not supported. -- | See <https://www.lua.org/manual/5.3/manual.html#lua_status lua_status> foreign import ccall unsafe "lua.h lua_status"- lua_status :: LuaState -> IO CInt+ lua_status :: LuaState -> IO StatusCode ---------------------------------------------------------------------------------+------------------------------------------------------------------------------ -- * Garbage-collection functions and options -- | See <https://www.lua.org/manual/5.3/manual.html#lua_gc lua_gc>@@ -421,88 +374,62 @@ lua_gc :: LuaState -> CInt -> CInt -> IO CInt ---------------------------------------------------------------------------------+------------------------------------------------------------------------------ -- * Miscellaneous functions --- | See <https://www.lua.org/manual/5.3/manual.html#lua_error lua_error>-foreign import ccall unsafe "lua.h lua_error"- lua_error :: LuaState -> IO CInt+-- lua_error is unsafe in a haskell context and hence not supported.+-- lua_next is unsafe, use hslua_next instead.+-- lua_concat is unsafe (may trigger a longjmp), use hslua_concat instead. --- | See <https://www.lua.org/manual/5.3/manual.html#lua_next lua_next>-foreign import ccall "lua.h lua_next"- lua_next :: LuaState -> CInt -> IO CInt+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_next \+-- @lua_next@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_next"+ hslua_next :: LuaState -> StackIndex -> IO (Failable LuaBool) --- | See <https://www.lua.org/manual/5.3/manual.html#lua_concat lua_concat>-foreign import ccall "lua.h lua_concat"- lua_concat :: LuaState -> CInt -> IO ()+-- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_concat \+-- @lua_concat@> which catches any @longjmp@s.+foreign import ccall "safer-api.h hslua_concat"+ hslua_concat :: LuaState -> NumArgs -> IO (Failable LuaBool) ++------------------------------------------------------------------------------+-- * Lua Libraries+ -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_openlibs luaL_openlibs> foreign import ccall unsafe "lualib.h luaL_openlibs" luaL_openlibs :: LuaState -> IO () --- | Opens the base library.-foreign import ccall unsafe "lualib.h luaopen_base"- lua_open_base :: LuaState -> IO CInt---- | Function pointer to @'lua_open_base'@+-- | Point to function opening the base library. foreign import ccall unsafe "lualib.h &luaopen_base"- lua_open_base_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the table library.-foreign import ccall unsafe "lualib.h luaopen_table"- lua_open_table :: LuaState -> IO CInt+ lua_open_base_ptr :: CFunction --- | Function pointer to @'lua_open_table'@+-- | Point to function opening the table library. foreign import ccall unsafe "lualib.h &luaopen_table"- lua_open_table_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the io library.-foreign import ccall unsafe "lualib.h luaopen_io"- lua_open_io :: LuaState -> IO CInt+ lua_open_table_ptr :: CFunction --- | Function pointer to @'lua_open_io'@+-- | Point to function opening the io library. foreign import ccall unsafe "lualib.h &luaopen_io"- lua_open_io_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the os library.-foreign import ccall unsafe "lualib.h luaopen_os"- lua_open_os :: LuaState -> IO CInt+ lua_open_io_ptr :: CFunction --- | Function pointer to @'lua_open_os'@+-- | Point to function opening the os library. foreign import ccall unsafe "lualib.h &luaopen_os"- lua_open_os_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the string library.-foreign import ccall unsafe "lualib.h luaopen_string"- lua_open_string :: LuaState -> IO CInt+ lua_open_os_ptr :: CFunction --- | Function pointer to @'lua_open_string'@+-- | Point to function opening the string library. foreign import ccall unsafe "lualib.h &luaopen_string"- lua_open_string_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the math library.-foreign import ccall unsafe "lualib.h luaopen_math"- lua_open_math :: LuaState -> IO CInt+ lua_open_string_ptr :: CFunction --- | Function pointer to @'lua_open_math'@+-- | Point to function opening the math library. foreign import ccall unsafe "lualib.h &luaopen_math"- lua_open_math_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the debug library.-foreign import ccall unsafe "lualib.h luaopen_debug"- lua_open_debug :: LuaState -> IO CInt+ lua_open_math_ptr :: CFunction --- | Function pointer to @'lua_open_debug'@+-- | Point to function opening the debug library. foreign import ccall unsafe "lualib.h &luaopen_debug"- lua_open_debug_ptr :: FunPtr (LuaState -> IO CInt)---- | Opens the package library.-foreign import ccall unsafe "lualib.h luaopen_package"- lua_open_package :: LuaState -> IO CInt+ lua_open_debug_ptr :: CFunction --- | Function pointer to @'lua_open_package'@+-- | Point to function opening the package library. foreign import ccall unsafe "lualib.h &luaopen_package"- lua_open_package_ptr :: FunPtr (LuaState -> IO CInt)+ lua_open_package_ptr :: CFunction --------------------------------------------------------------------------------@@ -514,30 +441,26 @@ -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_newmetatable luaL_newmetatable> foreign import ccall "lauxlib.h luaL_newmetatable"- luaL_newmetatable :: LuaState -> Ptr CChar -> IO CInt---- | See <https://www.lua.org/manual/5.3/manual.html#luaL_argerror luaL_argerror>-foreign import ccall "lauxlib.h luaL_argerror"- luaL_argerror :: LuaState -> CInt -> Ptr CChar -> IO CInt+ luaL_newmetatable :: LuaState -> Ptr CChar -> IO LuaBool -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_ref luaL_ref> foreign import ccall "lauxlib.h luaL_ref"- luaL_ref :: LuaState -> CInt -> IO CInt+ luaL_ref :: LuaState -> StackIndex -> IO CInt -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_unref luaL_unref> foreign import ccall "lauxlib.h luaL_unref"- luaL_unref :: LuaState -> CInt -> CInt -> IO ()+ luaL_unref :: LuaState -> StackIndex -> CInt -> IO () #if LUA_VERSION_NUMBER >= 502 -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_loadfilex luaL_loadfilex> foreign import ccall "lauxlib.h luaL_loadfilex"- luaL_loadfilex :: LuaState -> Ptr CChar -> Ptr CChar -> IO CInt+ luaL_loadfilex :: LuaState -> Ptr CChar -> Ptr CChar -> IO StatusCode #else -- | See <https://www.lua.org/manual/5.1/manual.html#luaL_loadfile luaL_loadfile> foreign import ccall "lauxlib.h luaL_loadfile"- luaL_loadfile :: LuaState -> Ptr CChar -> IO CInt+ luaL_loadfile :: LuaState -> Ptr CChar -> IO StatusCode #endif -- | See <https://www.lua.org/manual/5.3/manual.html#luaL_loadstring luaL_loadstring> foreign import ccall unsafe "lauxlib.h luaL_loadstring"- luaL_loadstring :: LuaState -> Ptr CChar -> IO CInt+ luaL_loadstring :: LuaState -> Ptr CChar -> IO StatusCode
− src/Foreign/Lua/Api/SafeBindings.hsc
@@ -1,73 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-|-Module : Foreign.Lua.Api.SafeBindings-Copyright : © 2017 Albert Krewinkel-License : MIT-Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>-Stability : beta-Portability : ForeignFunctionInterface--Haskell bindings to safe, @longjmp@ catching wrappers of Lua C API functions.--Functions in this module follow a custom protocol. If an error happens (i.e., if-the lua status is not 0), the status code is returned as a negative number.-Results of a successful execution of the wrapped function are returned as-non-negative numbers. This is possible because all (supported) lua API functions-are either safe and don't need wrapping, or return @void@, @size_t@ or a-non-negative @int@.--}-module Foreign.Lua.Api.SafeBindings where--import Foreign.C-import Foreign.Lua.Api.Types-import Foreign.Ptr--#include "safer-api.h"--#if LUA_VERSION_NUM >= 502--- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_compare \--- @lua_compare@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_compare"- hslua_compare :: LuaState -> CInt -> CInt -> CInt -> IO CInt-#endif---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_concat \--- @lua_concat@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_concat"- hslua_concat :: LuaState -> CInt -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_getfield \--- @lua_getfield@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_getfield"- hslua_getfield :: LuaState -> CInt -> Ptr CChar -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_getglobal \--- @lua_getglobal@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_getglobal"- hslua_getglobal :: LuaState -> Ptr CChar -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_gettable \--- @lua_gettable@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_gettable"- hslua_gettable :: LuaState -> CInt -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_next \--- @lua_next@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_next"- hslua_next :: LuaState -> CInt -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_setfield \--- @lua_setfield@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_setfield"- hslua_setfield :: LuaState -> CInt -> Ptr CChar -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_setglobal \--- @lua_setglobal@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_setglobal"- hslua_setglobal :: LuaState -> Ptr CChar -> IO CInt---- | Wrapper around <https://lua.org/manual/5.3/manual.html#lua_settable \--- @lua_settable@> which catches any @longjmp@s.-foreign import ccall "safer-api.h hslua_settable"- hslua_settable :: LuaState -> CInt -> IO CInt
src/Foreign/Lua/Api/Types.hsc view
@@ -39,11 +39,15 @@ -} module Foreign.Lua.Api.Types where -import Data.Int-import Foreign.C-import Foreign.Ptr+import Prelude hiding (EQ, LT)+import Data.Int (#{type LUA_INTEGER})+import Foreign.C (CInt)+import Foreign.Ptr (FunPtr, Ptr)+import Foreign.Storable (Storable) #include "lua.h"+-- required only for LUA_ERRFILE+#include "lauxlib.h" -- | 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@@ -53,23 +57,6 @@ -- Synonym for @lua_State *@. See <https://www.lua.org/manual/5.3/#lua_State lua_State>. newtype LuaState = LuaState (Ptr ()) deriving (Eq) --- | Synonym for @lua_Alloc@. See <https://www.lua.org/manual/5.3/#lua_Alloc lua_Alloc>.-type LuaAlloc = Ptr () -> Ptr () -> CSize -> CSize -> IO (Ptr ())---- | 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/#lua_Reader lua_Reader>.-type LuaReader = Ptr () -> Ptr () -> Ptr CSize -> IO (Ptr CChar)---- | Synonym for @lua_Writer@. See <https://www.lua.org/manual/5.3/#lua_Writer lua_Writer>.-type LuaWriter = LuaState -> Ptr CChar -> CSize -> Ptr () -> IO CInt- -- | Type for C functions. -- -- In order to communicate properly with Lua, a C function must use the@@ -85,7 +72,7 @@ -- can also return many results. -- -- See <https://www.lua.org/manual/5.3/manual.html#lua_CFunction lua_CFunction>.-type CFunction = FunPtr (LuaState -> IO CInt)+type CFunction = FunPtr (LuaState -> IO NumResults) -- | The type of integers in Lua. --@@ -103,99 +90,155 @@ -- See <https://www.lua.org/manual/5.3/manual.html#lua_Number lua_Number>. type LuaNumber = #{type LUA_NUMBER} ++--+-- 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)++-- | Convert a @'LuaBool'@ to a Haskell @'Bool'@.+fromLuaBool :: LuaBool -> Bool+fromLuaBool (LuaBool 0) = False+fromLuaBool _ = True++-- | Convert a Haskell @'Bool'@ to a @'LuaBool'@.+toLuaBool :: Bool -> LuaBool+toLuaBool True = LuaBool 1+toLuaBool False = LuaBool 0+++--+-- * Type of Lua values+--+ -- | Enumeration used as type tag. -- See <https://www.lua.org/manual/5.3/manual.html#lua_type lua_type>.-data LTYPE- = TNONE -- ^ non-valid stack index- | TNIL -- ^ type of lua's @nil@ value- | TBOOLEAN -- ^ type of lua booleans- | TLIGHTUSERDATA -- ^ type of light userdata- | TNUMBER -- ^ type of lua numbers. See @'LuaNumber'@- | TSTRING -- ^ type of lua string values- | TTABLE -- ^ type of lua tables- | TFUNCTION -- ^ type of functions, either normal or @'CFunction'@- | TUSERDATA -- ^ type of full user data- | TTHREAD -- ^ type of lua threads+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 @'LuaNumber'@+ | 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) -instance Enum LTYPE where- fromEnum TNONE = #{const LUA_TNONE}- fromEnum TNIL = #{const LUA_TNIL}- fromEnum TBOOLEAN = #{const LUA_TBOOLEAN}- fromEnum TLIGHTUSERDATA = #{const LUA_TLIGHTUSERDATA}- fromEnum TNUMBER = #{const LUA_TNUMBER}- fromEnum TSTRING = #{const LUA_TSTRING}- fromEnum TTABLE = #{const LUA_TTABLE}- fromEnum TFUNCTION = #{const LUA_TFUNCTION}- fromEnum TUSERDATA = #{const LUA_TUSERDATA}- fromEnum TTHREAD = #{const LUA_TTHREAD}+-- | Integer code used to encode the type of a lua value.+newtype TypeCode = TypeCode { fromTypeCode :: CInt }+ deriving (Eq, Ord, Show) - toEnum (#{const LUA_TNONE}) = TNONE- toEnum (#{const LUA_TNIL}) = TNIL- toEnum (#{const LUA_TBOOLEAN}) = TBOOLEAN- toEnum (#{const LUA_TLIGHTUSERDATA}) = TLIGHTUSERDATA- toEnum (#{const LUA_TNUMBER}) = TNUMBER- toEnum (#{const LUA_TSTRING}) = TSTRING- toEnum (#{const LUA_TTABLE}) = TTABLE- toEnum (#{const LUA_TFUNCTION}) = TFUNCTION- toEnum (#{const LUA_TUSERDATA}) = TUSERDATA- toEnum (#{const LUA_TTHREAD}) = TTHREAD- toEnum n = error $ "Cannot convert (" ++ show n ++ ") to LTYPE"+instance Enum Type where+ fromEnum = fromIntegral . fromTypeCode . fromType+ toEnum = toType . TypeCode . fromIntegral --- | Convert number to lua type.-toLuaType :: CInt -> LTYPE-toLuaType = toEnum . 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 Lua type to its C representation.-fromLuaType :: LTYPE -> CInt-fromLuaType = fromIntegral . fromEnum+-- | 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 LuaRelation- = LuaEQ -- ^ Correponds to lua's equality (==) operator.- | LuaLT -- ^ Correponds to lua's strictly-lesser-than (<) operator- | LuaLE -- ^ Correponds to lua's lesser-or-equal (<=) operator+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.-fromLuaRelation :: LuaRelation -> CInt+fromRelationalOperator :: RelationalOperator -> CInt #if LUA_VERSION_NUMBER >= 502-fromLuaRelation LuaEQ = #{const LUA_OPEQ}-fromLuaRelation LuaLT = #{const LUA_OPLT}-fromLuaRelation LuaLE = #{const LUA_OPLE}+fromRelationalOperator EQ = #{const LUA_OPEQ}+fromRelationalOperator LT = #{const LUA_OPLT}+fromRelationalOperator LE = #{const LUA_OPLE} #else-fromLuaRelation LuaEQ = 0-fromLuaRelation LuaLT = 1-fromLuaRelation LuaLE = 2+fromRelationalOperator EQ = 0+fromRelationalOperator LT = 1+fromRelationalOperator LE = 2 #endif ++--+-- * Status+--+ -- | Lua status values.-data LuaStatus- = LuaOK -- ^ success- | LuaYield -- ^ yielding / suspended coroutine- | LuaErrRun -- ^ a runtime rror- | LuaErrSyntax -- ^ syntax error during precompilation- | LuaErrMem -- ^ memory allocation (out-of-memory) error.- | LuaErrErr -- ^ error while running the message handler.- | LuaErrGcmm -- ^ error while running a @__gc@ metamethod.+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 @'LuaStatus'@.-toLuaStatus :: CInt -> LuaStatus--- LUA_OK is not defined in Lua 5.1-toLuaStatus 0 = LuaOK-toLuaStatus (#{const LUA_YIELD}) = LuaYield-toLuaStatus (#{const LUA_ERRRUN}) = LuaErrRun-toLuaStatus (#{const LUA_ERRSYNTAX}) = LuaErrSyntax-toLuaStatus (#{const LUA_ERRMEM}) = LuaErrMem--- LUA_ERRGCMM did not exist in Lua 5.1; comes before LUA_ERRERR when defined+toStatus :: StatusCode -> Status+toStatus (StatusCode c) = case c of+ -- LUA_OK is not defined in Lua 5.1+ 0 -> OK+ (#{const LUA_YIELD}) -> Yield+ (#{const LUA_ERRRUN}) -> ErrRun+ (#{const LUA_ERRSYNTAX}) -> ErrSyntax+ (#{const LUA_ERRMEM}) -> ErrMem+ -- LUA_ERRGCMM did not exist in Lua 5.1; comes before LUA_ERRERR when defined #if LUA_VERSION_NUMBER >= 502-toLuaStatus (#{const LUA_ERRGCMM}) = LuaErrGcmm-toLuaStatus (#{const LUA_ERRERR}) = LuaErrErr+ (#{const LUA_ERRGCMM}) -> ErrGcmm+ (#{const LUA_ERRERR}) -> ErrErr #else-toLuaStatus (#{const LUA_ERRERR}) = LuaErrErr+ (#{const LUA_ERRERR}) -> ErrErr #endif-toLuaStatus n = error $ "Cannot convert (" ++ show n ++ ") to LuaStatus"+ (#{const LUA_ERRFILE}) -> ErrFile+ n -> error $ "Cannot convert (" ++ show n ++ ") to LuaStatus"++-- | Integer code used to signal the status of a thread or computation.+-- See @'Status'@.+newtype StatusCode = StatusCode CInt deriving Eq++-- | Value or an error, using the convention that value below zero indicate an+-- error. Values greater than zero are used verbatim. The phantom type is+-- currently used for documentation only and has no effect.+type Failable a = CInt+++--+-- * Gargabe Collection Control+-- -- | Enumeration used by @gc@ function. data GCCONTROL
src/Foreign/Lua/FunctionCalling.hs view
@@ -133,7 +133,7 @@ getglobal' fnName x z <- pcall nargs 1 Nothing- if z /= LuaOK+ if z /= OK then tostring (-1) >>= throwLuaError . unpack else peek (-1) <* pop 1
src/Foreign/Lua/Types/FromLuaStack.hs view
@@ -44,6 +44,7 @@ , Result , peekEither , pairsFromTable+ , toList ) where import Data.ByteString (ByteString)@@ -60,12 +61,34 @@ -- | Result returned when trying to get a value from the lua stack. type Result a = Either String a +-- | Use @test@ to check whether the value at stack index @n@ has the correct+-- type and use @peekfn@ to convert it to a haskell value if possible. A+-- successfully received value is wrapped using the @'Success'@ constructor,+-- while a type mismatch results in an @Error@ with the given error message.+typeChecked :: String+ -> (StackIndex -> Lua Bool)+ -> (StackIndex -> Lua a)+ -> StackIndex+ -> Lua a+typeChecked expectedType test peekfn n = do+ v <- test n+ if v+ then peekfn n+ else do+ actual <- ltype n >>= typename+ throwLuaError $ "Expected a " <> expectedType <> " but got a " <> actual+ -- | A value that can be read from the Lua stack. class FromLuaStack a where -- | Check if at index @n@ there is a convertible Lua value and if so return -- it. Throws a @'LuaException'@ otherwise. peek :: StackIndex -> Lua a +-- | Try to convert the value at the given stack index to a haskell value.+-- Returns @Left@ with an error message on failure.+peekEither :: FromLuaStack a => StackIndex -> Lua (Either String a)+peekEither idx = catchLuaError (return <$> peek idx) (return . Left . show)+ instance FromLuaStack () where peek = typeChecked "nil" isnil (const $ return ()) @@ -104,17 +127,21 @@ peek = fmap T.unpack . peek instance FromLuaStack a => FromLuaStack [a] where- peek n = catchLuaError (go . enumFromTo 1 =<< rawlen n) amendError- where- go [] = return []- go (i : is) = do- ret <- rawgeti n i *> peek (-1) <* pop 1- (ret:) <$> go is- amendError err = throwLuaError ("Could not read list: " ++ show err)+ peek = toList instance (Ord a, FromLuaStack a, FromLuaStack b) => FromLuaStack (Map a b) where peek idx = fromList <$> pairsFromTable idx +-- | Read a table into a list+toList :: FromLuaStack a => StackIndex -> Lua [a]+toList n = (go . enumFromTo 1 =<< rawlen n) `catchLuaError` amendError+ where+ go [] = return []+ go (i : is) = do+ ret <- rawgeti n i *> peek (-1) <* pop 1+ (ret:) <$> go is+ amendError err = throwLuaError ("Could not read list: " ++ show err)+ -- | Read a table into a list of pairs. pairsFromTable :: (FromLuaStack a, FromLuaStack b) => StackIndex -> Lua [(a, b)] pairsFromTable idx = do@@ -140,24 +167,101 @@ return (Just (k, v)) else return Nothing --- | Use @test@ to check whether the value at stack index @n@ has the correct--- type and use @peekfn@ to convert it to a haskell value if possible. A--- successfully received value is wrapped using the @'Success'@ constructor,--- while a type mismatch results in an @Error@ with the given error message.-typeChecked :: String- -> (StackIndex -> Lua Bool)- -> (StackIndex -> Lua a)- -> StackIndex- -> Lua a-typeChecked expectedType test peekfn n = do- v <- test n- if v- then peekfn n- else do- actual <- ltype n >>= typename- throwLuaError $ "Expected a " <> expectedType <> " but got a " <> actual+--+-- Tuples+-- --- | Try to convert the value at the given stack index to a haskell value.--- Returns @Left@ with an error message on failure.-peekEither :: FromLuaStack a => StackIndex -> Lua (Either String a)-peekEither idx = catchLuaError (return <$> peek idx) (return . Left . show)+instance (FromLuaStack a, FromLuaStack b) => FromLuaStack (a, b) where+ peek idx = do+ a <- rawgeti idx 1 *> peek (-1) <* pop 1+ b <- rawgeti idx 2 *> peek (-1) <* pop 1+ return (a, b)++instance (FromLuaStack a, FromLuaStack b, FromLuaStack c) =>+ FromLuaStack (a, b, c)+ where+ peek idx = do+ pushvalue idx+ a <- getTableIndex 1+ b <- getTableIndex 2+ c <- getTableIndex 3+ pop 4+ return (a, b, c)++instance (FromLuaStack a, FromLuaStack b, FromLuaStack c, FromLuaStack d) =>+ FromLuaStack (a, b, c, d)+ where+ peek idx = do+ pushvalue idx+ a <- getTableIndex 1+ b <- getTableIndex 2+ c <- getTableIndex 3+ d <- getTableIndex 4+ pop 5+ return (a, b, c, d)++instance (FromLuaStack a, FromLuaStack b, FromLuaStack c,+ FromLuaStack d, FromLuaStack e) =>+ FromLuaStack (a, b, c, d, e)+ where+ peek idx = do+ pushvalue idx+ a <- getTableIndex 1+ b <- getTableIndex 2+ c <- getTableIndex 3+ d <- getTableIndex 4+ e <- getTableIndex 5+ pop 6+ return (a, b, c, d, e)++instance (FromLuaStack a, FromLuaStack b, FromLuaStack c,+ FromLuaStack d, FromLuaStack e, FromLuaStack f) =>+ FromLuaStack (a, b, c, d, e, f)+ where+ peek idx = do+ pushvalue idx+ a <- getTableIndex 1+ b <- getTableIndex 2+ c <- getTableIndex 3+ d <- getTableIndex 4+ e <- getTableIndex 5+ f <- getTableIndex 6+ pop 7+ return (a, b, c, d, e, f)++instance (FromLuaStack a, FromLuaStack b, FromLuaStack c, FromLuaStack d,+ FromLuaStack e, FromLuaStack f, FromLuaStack g) =>+ FromLuaStack (a, b, c, d, e, f, g)+ where+ peek idx = do+ pushvalue idx+ a <- getTableIndex 1+ b <- getTableIndex 2+ c <- getTableIndex 3+ d <- getTableIndex 4+ e <- getTableIndex 5+ f <- getTableIndex 6+ g <- getTableIndex 7+ pop 8+ return (a, b, c, d, e, f, g)++instance (FromLuaStack a, FromLuaStack b, FromLuaStack c, FromLuaStack d,+ FromLuaStack e, FromLuaStack f, FromLuaStack g, FromLuaStack h) =>+ FromLuaStack (a, b, c, d, e, f, g, h)+ where+ peek idx = do+ pushvalue idx+ a <- getTableIndex 1+ b <- getTableIndex 2+ c <- getTableIndex 3+ d <- getTableIndex 4+ e <- getTableIndex 5+ f <- getTableIndex 6+ g <- getTableIndex 7+ h <- getTableIndex 8+ pop 9+ return (a, b, c, d, e, f, g, h)++-- | Helper function to get the nth table value+getTableIndex :: FromLuaStack b => Int -> Lua b+getTableIndex key = rawgeti (StackIndex (- (fromIntegral key))) key *> peek (-1)
src/Foreign/Lua/Types/ToLuaStack.hs view
@@ -41,6 +41,7 @@ -} module Foreign.Lua.Types.ToLuaStack ( ToLuaStack (..)+ , pushList ) where import Control.Monad (zipWithM_)@@ -94,13 +95,105 @@ push = push . T.pack instance ToLuaStack a => ToLuaStack [a] where- push xs = do- let setField i x = push x *> rawseti (-2) i- newtable- zipWithM_ setField [1..] xs+ push = pushList +-- | Push list as numerically indexed table.+pushList :: ToLuaStack a => [a] -> Lua ()+pushList xs = do+ let setField i x = push x *> rawseti (-2) i+ newtable+ zipWithM_ setField [1..] xs+ instance (ToLuaStack a, ToLuaStack b) => ToLuaStack (Map a b) where push m = do let addValue (k, v) = push k *> push v *> rawset (-3) newtable mapM_ addValue (toList m)++--+-- Tuples+--+instance (ToLuaStack a, ToLuaStack b) => ToLuaStack (a, b) where+ push (a, b) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b++instance (ToLuaStack a, ToLuaStack b, ToLuaStack c) =>+ ToLuaStack (a, b, c)+ where+ push (a, b, c) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b+ addRawInt 3 c++instance (ToLuaStack a, ToLuaStack b, ToLuaStack c, ToLuaStack d) =>+ ToLuaStack (a, b, c, d)+ where+ push (a, b, c, d) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b+ addRawInt 3 c+ addRawInt 4 d++instance (ToLuaStack a, ToLuaStack b, ToLuaStack c,+ ToLuaStack d, ToLuaStack e) =>+ ToLuaStack (a, b, c, d, e)+ where+ push (a, b, c, d, e) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b+ addRawInt 3 c+ addRawInt 4 d+ addRawInt 5 e++instance (ToLuaStack a, ToLuaStack b, ToLuaStack c,+ ToLuaStack d, ToLuaStack e, ToLuaStack f) =>+ ToLuaStack (a, b, c, d, e, f)+ where+ push (a, b, c, d, e, f) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b+ addRawInt 3 c+ addRawInt 4 d+ addRawInt 5 e+ addRawInt 6 f++instance (ToLuaStack a, ToLuaStack b, ToLuaStack c, ToLuaStack d,+ ToLuaStack e, ToLuaStack f, ToLuaStack g) =>+ ToLuaStack (a, b, c, d, e, f, g)+ where+ push (a, b, c, d, e, f, g) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b+ addRawInt 3 c+ addRawInt 4 d+ addRawInt 5 e+ addRawInt 6 f+ addRawInt 7 g++instance (ToLuaStack a, ToLuaStack b, ToLuaStack c, ToLuaStack d,+ ToLuaStack e, ToLuaStack f, ToLuaStack g, ToLuaStack h) =>+ ToLuaStack (a, b, c, d, e, f, g, h)+ where+ push (a, b, c, d, e, f, g, h) = do+ newtable+ addRawInt 1 a+ addRawInt 2 b+ addRawInt 3 c+ addRawInt 4 d+ addRawInt 5 e+ addRawInt 6 f+ addRawInt 7 g+ addRawInt 8 h++-- | Set numeric key/value in table at the top of the stack.+addRawInt :: ToLuaStack a => Int -> a -> Lua ()+addRawInt idx val = do+ push val+ rawseti (-2) idx
test/Foreign/Lua/ApiTest.hs view
@@ -38,7 +38,7 @@ import Prelude hiding (compare) import Control.Monad (forM_)-import Foreign.Lua+import Foreign.Lua as Lua import Test.HsLua.Util (luaTestCase, pushLuaExpr) import Test.QuickCheck (Property, (.&&.)) import Test.QuickCheck.Arbitrary (Arbitrary (..), arbitraryBoundedEnum)@@ -48,6 +48,7 @@ import Test.Tasty.QuickCheck (testProperty) import qualified Prelude+import qualified Foreign.Lua.Api.RawBindings as LuaRaw -- | Specifications for Attributes parsing functions.@@ -93,16 +94,56 @@ slen <- strlen (-1) return $ rlen == olen && rlen == slen && rlen == 6 - , luaTestCase "isfunction" $ do- pushLuaExpr "function () print \"hi!\" end"- isfunction (-1)+ , testGroup "Type checking"+ [ luaTestCase "isfunction" $ do+ pushLuaExpr "function () print \"hi!\" end"+ isfunction (-1) - , luaTestCase "isnil" $ pushLuaExpr "nil" *> isnil (-1)- , luaTestCase "isnone" $ isnone 500 -- stack index 500 does not exist- , luaTestCase "isnoneornil" $ do- pushLuaExpr "nil"- (&&) <$> isnoneornil 500 <*> isnoneornil (-1)+ , luaTestCase "isnil" $ pushLuaExpr "nil" *> isnil (-1) + , luaTestCase "isnone" $ isnone 500 -- stack index 500 does not exist++ , luaTestCase "isnoneornil" $ do+ pushLuaExpr "nil"+ (&&) <$> isnoneornil 500 <*> isnoneornil (-1)+ ]++ , testCase "CFunction handling" . runLua $ do+ pushcfunction LuaRaw.lua_open_debug_ptr+ liftIO . assertBool "not recognized as CFunction" =<< iscfunction (-1)+ liftIO . assertEqual "CFunction changed after receiving it from the stack"+ LuaRaw.lua_open_debug_ptr =<< tocfunction (-1)++ , testGroup "getting values"+ [ testCase "tointegerx returns numbers verbatim" . runLua $ do+ pushLuaExpr "149"+ res <- tointegerx (-1)+ liftIO $ assertEqual "Not the correct number" (Just 149) res++ , testCase "tointegerx accepts strings coercible to integers" . runLua $ do+ pushLuaExpr "'451'"+ res <- tointegerx (-1)+ liftIO $ assertEqual "Not the correct number" (Just 451) res++ , testCase "tointegerx returns Nothing when given a boolean" . runLua $ do+ pushLuaExpr "true"+ liftIO . assertEqual "Not the correct number" Nothing =<< tointegerx (-1)++ , testCase "tonumberx returns numbers verbatim" . runLua $ do+ pushLuaExpr "14.9"+ res <- tonumberx (-1)+ liftIO $ assertEqual "Not the correct number" (Just 14.9) res++ , testCase "tonumberx accepts strings as numbers" . runLua $ do+ pushLuaExpr "'42.23'"+ res <- tonumberx (-1)+ liftIO $ assertEqual "Not the correct number" (Just 42.23) res++ , testCase "tonumberx returns Nothing when given a boolean" . runLua $ do+ pushLuaExpr "true"+ liftIO . assertEqual "Not the correct number" Nothing =<< tonumberx (-1)+ ]+ , luaTestCase "setting and getting a global works" $ do pushLuaExpr "{'Moin', Hello = 'World'}" setglobal "hamburg"@@ -126,27 +167,63 @@ assertBool "different lua threads are equal in haskell" (luaSt1 /= luaSt2) , testCase "thread status" . runLua $ do- status >>= liftIO . assertEqual "base status should be OK" LuaOK+ status >>= liftIO . assertEqual "base status should be OK" OK openlibs getglobal' "coroutine.resume" pushLuaExpr "coroutine.create(function() coroutine.yield(9) end)" co <- tothread (-1) call 1 0 liftIO . runLuaWith co $ do- liftIO . assertEqual "yielding will put thread status to Yield" LuaYield+ liftIO . assertEqual "yielding will put thread status to Yield" Yield =<< status - , testCase "loadstring status" . runLua $ do- liftIO . assertEqual "loading a valid string doesn't return LuaOK"- LuaOK =<< loadstring "return 1"- liftIO . assertEqual "loading an invalid string doesn't return LuaErrSyntax"- LuaErrSyntax =<< loadstring "marzipan"+ , testGroup "loading"+ [ testCase "loadstring status" . runLua $ do+ liftIO . assertEqual "loading a valid string doesn't return OK"+ OK =<< loadstring "return 1"+ liftIO . assertEqual "loading an invalid string doesn't return ErrSyntax"+ ErrSyntax =<< loadstring "marzipan" + , testCase "dostring loading" . runLua $ do+ liftIO . assertEqual "wrong dostring result"+ ErrRun =<< (dostring "error 'this fails'")+ liftIO . assertEqual "loading an invalid string doesn't return ErrSyntax"+ ErrSyntax =<< dostring "marzipan"+ liftIO . assertEqual "loading a valid program failed"+ OK =<< dostring "return (2 + 3)"+ liftIO . assertEqual "top of the stack should be result of last computation"+ (5 :: LuaInteger) =<< peek (-1)++ , testCase "loadfile loading" . runLua $ do+ liftIO . assertEqual "wrong error code for non-existing file"+ ErrFile =<< loadfile "./file-does-not-exist.lua"+ liftIO . assertEqual "loading an invalid file doesn't return ErrSyntax"+ ErrSyntax =<< loadfile "test/lua/syntax-error.lua"+ liftIO . assertEqual "loading a valid program failed"+ OK =<< loadfile "./test/lua/example.lua"+ call 0 0+ liftIO . assertEqual "fib function not defined or not correct"+ (8 :: LuaInteger) =<< (getglobal "fib" *> pushinteger 6 *>+ call 1 1 *> peek (-1))++ , testCase "dofile loading" . runLua $ do+ liftIO . assertEqual "wrong error code for non-existing file"+ ErrFile =<< dofile "./file-does-not-exist.lua"+ liftIO . assertEqual "loading an invalid file doesn't return ErrSyntax"+ ErrSyntax =<< dofile "test/lua/syntax-error.lua"+ liftIO . assertEqual "wrong dofile result"+ ErrRun =<< dofile "test/lua/error.lua"+ liftIO . assertEqual "loading a valid program failed"+ OK =<< dofile "./test/lua/example.lua"+ liftIO . assertEqual "fib function not defined or not correct"+ (13 :: LuaInteger) =<< dostring "return fib(7)" *> peek (-1)+ ]+ , testCase "pcall status" . runLua $ do liftIO . assertEqual "calling error did not lead to an error status"- LuaErrRun =<< (loadstring "error \"this fails\"" *> pcall 0 0 Nothing)+ ErrRun =<< (loadstring "error \"this fails\"" *> pcall 0 0 Nothing) liftIO . assertEqual "calling error did not lead to an error status"- LuaErrErr =<< do+ ErrErr =<< do pushLuaExpr "function () error 'error in error handler' end" loadstring "error 'this fails'" *> pcall 0 0 (Just (-2)) @@ -155,9 +232,9 @@ forM_ [GCSTOP .. GCSETSTEPMUL] $ \what -> (gc what 23) , testGroup "compare"- [ testProperty "identifies strictly smaller values" $ compareWith (<) LuaLT- , testProperty "identifies smaller or equal values" $ compareWith (<=) LuaLE- , testProperty "identifies equal values" $ compareWith (==) LuaEQ+ [ testProperty "identifies strictly smaller values" $ compareWith (<) Lua.LT+ , testProperty "identifies smaller or equal values" $ compareWith (<=) Lua.LE+ , testProperty "identifies equal values" $ compareWith (==) Lua.EQ ] , testProperty "lessthan works" $ \n1 n2 -> monadicIO $ do@@ -168,12 +245,12 @@ assert $ luaCmp == (n1 < n2) , testProperty "order of Lua types is consistent" $ \ lt1 lt2 ->- let n1 = fromLuaType (lt1 :: LTYPE)- n2 = fromLuaType lt2+ let n1 = fromType lt1+ n2 = fromType lt2 in Prelude.compare n1 n2 == Prelude.compare lt1 lt2 ] -compareWith :: (Int -> Int -> Bool) -> LuaRelation -> Int -> Property+compareWith :: (Int -> Int -> Bool) -> RelationalOperator -> Int -> Property compareWith op luaOp n = compareLT .&&. compareEQ .&&. compareGT where compareLT :: Property@@ -200,5 +277,5 @@ compare (-2) (-1) luaOp assert $ luaRes == op (n + 1) n -instance Arbitrary LTYPE where+instance Arbitrary Type where arbitrary = arbitraryBoundedEnum
test/Foreign/Lua/TypesTest.hs view
@@ -74,6 +74,28 @@ , testProperty "map of strings to LuaNumber" (prop_roundtripEqual :: Map String LuaNumber -> Property)++ , testGroup "tuples"+ [ testProperty "pair of LuaNumbers"+ (prop_roundtripEqual :: (LuaNumber, LuaNumber) -> Property)+ , testProperty "triple of LuaNumbers"+ (prop_roundtripEqual :: (LuaNumber, LuaNumber, LuaNumber) -> Property)+ , testProperty "quadruple of LuaNumbers"+ (prop_roundtripEqual+ :: (LuaNumber, LuaNumber, LuaNumber, LuaNumber) -> Property)+ , testProperty "quintuple of LuaNumbers"+ (prop_roundtripEqual+ :: (LuaNumber, LuaNumber, LuaNumber, LuaNumber, LuaNumber) -> Property)+ , testProperty "hextuple of Text, LuaNumbers and Booleans"+ (prop_roundtripEqual+ :: (Bool, LuaNumber, T.Text, Bool, LuaNumber, LuaNumber) -> Property)+ , testProperty "septuple of Text, LuaNumber and Booleans"+ (prop_roundtripEqual+ :: (T.Text, Bool, LuaNumber, Bool, Bool, LuaNumber, Bool) -> Property)+ , testProperty "octuple of Strings and Booleans"+ (prop_roundtripEqual+ :: (Bool, String, Bool, Bool, String, Bool, Bool, String) -> Property)+ ] ] , testGroup "Random stack values"
test/Foreign/LuaTest.hs view
@@ -58,7 +58,7 @@ idx1 <- ref registryindex idx2 <- ref registryindex -- functions are removed from stack- liftIO . assert =<< fmap (TFUNCTION /=) (ltype (-1))+ liftIO . assert =<< fmap (TypeFunction /=) (ltype (-1)) -- get functions from registry rawgeti registryindex idx1@@ -197,7 +197,7 @@ (runLuaEither $ do openbase res <- loadstring luaCode- when (res == LuaOK) $ call 0 0)+ when (res == OK) $ call 0 0) ] ]
+ test/lua/error.lua view
@@ -0,0 +1,1 @@+error 'running this program will cause an error'
+ test/lua/example.lua view
@@ -0,0 +1,8 @@+--- Compute the n-th fibonacci number.+function fib(n)+ local a, b = 0, 1+ for i = 0, (n - 1) do+ a, b = b, b + a+ end+ return a+end
+ test/lua/syntax-error.lua view
@@ -0,0 +1,1 @@+just wrong