@@ -13,6 +13,7 @@ module Python.Inline.Literal
1313import Control.Exception
1414import Control.Monad
1515import Control.Monad.IO.Class
16+ import Control.Monad.Trans.Class
1617import Control.Monad.Trans.Cont
1718import Data.Int
1819import Data.Word
@@ -28,6 +29,7 @@ import Language.C.Inline.Unsafe qualified as CU
2829import Python.Types
2930import Python.Internal.Types
3031import Python.Internal.Eval
32+ import Python.Internal.Util
3133
3234
3335----------------------------------------------------------------
@@ -143,6 +145,60 @@ instance ToPy Int where
143145instance FromPy Int where
144146 basicFromPy = (fmap . fmap ) fromIntegral . basicFromPy @ Int64
145147
148+ -- TODO: Int may be 32 or 64 bit!
149+ -- TODO: Int{8,16,32} & Word{8,16,32}
150+
151+ instance ToPy Bool where
152+ basicToPy True = Py [CU. exp | PyObject* { Py_True } |]
153+ basicToPy False = Py [CU. exp | PyObject* { Py_False } |]
154+
155+ -- | Uses python's truthiness conventions
156+ instance FromPy Bool where
157+ basicFromPy p = Py $ do
158+ r <- [CU. block | int {
159+ int r = PyObject_IsTrue($(PyObject* p));
160+ PyErr_Clear();
161+ return r;
162+ } |]
163+ case r of
164+ 0 -> pure $ Just False
165+ 1 -> pure $ Just True
166+ _ -> pure $ Nothing
167+
168+ instance (ToPy a , ToPy b ) => ToPy (a ,b ) where
169+ basicToPy (a,b) = do
170+ basicToPy a >>= \ case
171+ NULL -> pure NULL
172+ p_a -> basicToPy b >>= \ case
173+ NULL -> pure $ NULL
174+ p_b -> Py [CU. exp | PyObject* { PyTuple_Pack(2, $(PyObject* p_a), $(PyObject* p_b)) } |]
175+
176+ instance (FromPy a , FromPy b ) => FromPy (a ,b ) where
177+ basicFromPy p_tup = evalContT $ do
178+ -- Unpack 2-tuple.
179+ p_args <- withPyAllocaArray 2
180+ unpack_ok <- liftIO [CU. exp | int {
181+ inline_py_unpack_iterable($(PyObject *p_tup), 2, $(PyObject **p_args))
182+ }|]
183+ -- We may want to extract exception to haskell side later
184+ liftIO [CU. exp | void { PyErr_Clear() } |]
185+ when (unpack_ok /= 0 ) $ abort $ pure Nothing
186+ -- Unpack 2-elements
187+ lift $ do
188+ p_a <- liftIO $ peekElemOff p_args 0
189+ p_b <- liftIO $ peekElemOff p_args 1
190+ let parse = basicFromPy p_a >>= \ case
191+ Nothing -> pure Nothing
192+ Just a -> basicFromPy p_b >>= \ case
193+ Nothing -> pure Nothing
194+ Just b -> pure $ Just (a,b)
195+ fini = liftIO [CU. block | void {
196+ Py_XDECREF( $(PyObject* p_a) );
197+ Py_XDECREF( $(PyObject* p_b) );
198+ } |]
199+ parse `finallyPy` fini
200+
201+
146202
147203----------------------------------------------------------------
148204-- Functions marshalling
0 commit comments