synthesizer-llvm-0.2: src/Synthesizer/LLVM/Storable/LazySizeIterator.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Synthesizer.LLVM.Storable.LazySizeIterator where
import qualified Numeric.NonNegative.Chunky as Chunky
import qualified Data.StorableVector.Lazy.Pattern as SVP
import qualified Data.StorableVector.Lazy as SVL
import Data.Word (Word32, )
import Foreign.StablePtr (StablePtr, newStablePtr, freeStablePtr, deRefStablePtr, )
import Foreign.Ptr (FunPtr, )
import Data.IORef (IORef, newIORef, readIORef, writeIORef, )
import qualified Data.List.HT as ListHT
newtype T = Cons (IORef [SVL.ChunkSize])
{-
For problems about Storable constraint, see ChunkIterator.
-}
foreign import ccall "&nextSize"
nextCallBack ::
FunPtr (StablePtr T -> IO Word32)
foreign export ccall "nextSize"
next :: StablePtr T -> IO Word32
new ::
SVP.LazySize -> IO (StablePtr T)
new ls =
newStablePtr . Cons =<< newIORef (Chunky.toChunks (Chunky.normalize ls))
dispose ::
StablePtr T -> IO ()
dispose = freeStablePtr
{- |
Zero pieces are filtered out.
If 'next' returns 0 then the end of the lazy size is reached.
-}
next ::
StablePtr T -> IO Word32
next stable =
deRefStablePtr stable >>= \state ->
case state of
Cons listRef ->
readIORef listRef >>=
ListHT.switchL
(return 0)
(\(SVL.ChunkSize time) xs ->
writeIORef listRef xs >>
return (fromIntegral time))