{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-| Module : Foreign.Lua.Types.Pushable Copyright : © 2007–2012 Gracjan Polak, 2012–2016 Ömer Sinan Ağacan, 2017-2020 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel Stability : beta Portability : FlexibleInstances, ScopedTypeVariables Sending haskell objects to the lua stack. -} module Foreign.Lua.Types.Pushable ( Pushable (..) , pushList ) where import Data.ByteString (ByteString) import Data.Map (Map) import Data.Text (Text) import Data.Set (Set) import Foreign.Lua.Core as Lua import Foreign.Lua.Push as Push import Foreign.Ptr (Ptr) import qualified Data.ByteString.Lazy as BL -- | A value that can be pushed to the Lua stack. class Pushable a where -- | Pushes a value onto Lua stack, casting it into meaningfully nearest Lua -- type. push :: a -> Lua () instance Pushable () where push = const pushnil instance Pushable Lua.Integer where push = pushinteger instance Pushable Lua.Number where push = pushnumber instance Pushable ByteString where push = pushstring instance Pushable Bool where push = pushboolean instance Pushable CFunction where push = pushcfunction instance Pushable (Ptr a) where push = pushlightuserdata instance Pushable Text where push = pushText instance Pushable BL.ByteString where push = pushLazyByteString instance Pushable Prelude.Integer where push = pushIntegral instance Pushable Int where push = pushIntegral instance Pushable Float where push = pushRealFloat instance Pushable Double where push = pushRealFloat instance {-# OVERLAPS #-} Pushable [Char] where push = pushString instance Pushable a => Pushable [a] where push = pushList push instance (Pushable a, Pushable b) => Pushable (Map a b) where push = pushMap push push instance Pushable a => Pushable (Set a) where push = pushSet push -- -- Tuples -- instance (Pushable a, Pushable b) => Pushable (a, b) where push (a, b) = do newtable addRawInt 1 a addRawInt 2 b instance (Pushable a, Pushable b, Pushable c) => Pushable (a, b, c) where push (a, b, c) = do newtable addRawInt 1 a addRawInt 2 b addRawInt 3 c instance (Pushable a, Pushable b, Pushable c, Pushable d) => Pushable (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 (Pushable a, Pushable b, Pushable c, Pushable d, Pushable e) => Pushable (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 (Pushable a, Pushable b, Pushable c, Pushable d, Pushable e, Pushable f) => Pushable (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 (Pushable a, Pushable b, Pushable c, Pushable d, Pushable e, Pushable f, Pushable g) => Pushable (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 (Pushable a, Pushable b, Pushable c, Pushable d, Pushable e, Pushable f, Pushable g, Pushable h) => Pushable (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 :: Pushable a => Lua.Integer -> a -> Lua () addRawInt idx val = do push val rawseti (-2) idx