1- {-# OPTIONS_GHC -fprof-auto #-}
1+ {-# OPTIONS_GHC -fprof-auto #-}
2+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
23{-# LANGUAGE FlexibleInstances #-}
34{-# LANGUAGE UndecidableInstances #-}
5+ {-# LANGUAGE BangPatterns #-}
46module Data.BitCode.Writer.Monad
57 ( BitCodeWriter
68 , evalBitCodeWriter , execBitCodeWriter
@@ -24,21 +26,36 @@ import Data.ByteString.Base16 (encode)
2426
2527import Data.BitCode
2628
29+ import Control.Monad.Trans.State
30+
2731import Data.Sequence (Seq (.. ), fromList )
2832import Data.Foldable (toList )
2933
34+ import GHC.Stack (HasCallStack )
35+
3036-- * BitCode
31- data BitC = BitC { _words :: Int , _bits :: Int , _body :: Seq Bool } deriving (Show )
37+ data BitC = BitC { _words :: Int
38+ , _bits :: Int
39+ , _body :: (Seq Bool )
40+ } deriving (Show )
3241
3342instance Monoid BitC where
3443 mempty = BitC 0 0 mempty
35- (BitC w l bs) `mappend` (BitC w' l' bs') = BitC (w + w' + (( l+ l') `div ` 32 )) ((l + l') `mod` 32 ) (bs `mappend` bs')
44+ mappend ! (BitC w l bs) ! (BitC w' l' bs') = let ( ! d, ! m) = ( l+ l') `divMod ` 32 in BitC (w + w' + d) m (bs `mappend` bs')
3645
3746-- * BitCode Writer Monad (with access to the current state)
38- newtype BitCodeWriter a = BitCode { unBitCode :: BitC -> (a , BitC ) }
47+ newtype BitCodeWriter a = BitCode { unBitCode :: State BitC a }
48+ deriving (Functor , Applicative , Monad )
49+
50+ modifyBits :: HasCallStack => (BitC -> BitC ) -> BitCodeWriter ()
51+ modifyBits = BitCode . modify
52+ modifyBits' :: HasCallStack => (BitC -> BitC ) -> BitCodeWriter ()
53+ modifyBits' = BitCode . modify'
54+ getsBits :: HasCallStack => (BitC -> a ) -> BitCodeWriter a
55+ getsBits = BitCode . gets
3956
4057runBitCodeWriter :: BitCodeWriter a -> (a , BitC )
41- runBitCodeWriter = flip unBitCode mempty
58+ runBitCodeWriter = flip runState mempty . unBitCode
4259
4360evalBitCodeWriter :: BitCodeWriter a -> a
4461evalBitCodeWriter = fst . runBitCodeWriter
@@ -49,40 +66,25 @@ execBitCodeWriter = toList . _body . snd . runBitCodeWriter
4966class ToBits a where
5067 emit :: a -> BitCodeWriter ()
5168
52- -- * Functor
53- instance Functor BitCodeWriter where
54- fmap f m = BitCode $ \ b -> let (a, b') = unBitCode m b
55- in (f a, b')
56- -- * Applicative
57- instance Applicative BitCodeWriter where
58- pure a = BitCode $ \ b -> (a, b)
59-
60- m <*> n = BitCode $ \ b ->
61- let (f, b') = unBitCode m b
62- (x, b'') = unBitCode n b'
63- in (f x, b' `mappend` b'')
64-
65- -- * Monad
66- instance Monad BitCodeWriter where
67- m >>= n = BitCode $ \ b -> let (a, b') = unBitCode m b in unBitCode (n a) b'
68-
69+ {-
6970-- * Monoid
7071instance Monoid (BitCodeWriter ()) where
7172 mempty = pure ()
7273 m `mappend` n = BitCode $ \b ->
7374 let (_, a) = unBitCode m b
7475 (_, b) = unBitCode n b
7576 in ((), a `mappend` b)
77+ -}
7678
7779-- * Low Level BitCode Functions (These need to know about BitCode and BitC)
7880tell :: Bits -> BitCodeWriter ()
79- tell bs = BitCode $ \ b -> ( () , b `mappend` b')
80- where n = length bs
81- b' = BitC (n `div` 32 ) (n `mod` 32 ) (fromList bs)
81+ tell bs = modifyBits' ( \ b -> b `mappend` b')
82+ where ! n = length bs
83+ ! b' = BitC (n `div` 32 ) (n `mod` 32 ) (fromList bs)
8284
8385-- | Get the number of words and bits in the stream.
8486ask :: BitCodeWriter (Int , Int )
85- ask = BitCode $ \ b @ (BitC ws bs _) -> (( ws,bs),b )
87+ ask = getsBits ( \ (BitC ws bs _) -> (ws,bs))
8688
8789-- * Utility
8890
0 commit comments