X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FbasicTypes%2FUniqSupply.lhs;h=2599d8d5f0f3e3bf1fdc0984583ed8f21f715b79;hb=992bdde6de529002406a63abf94cb3e8a644bf3b;hp=41ad5c0f60dadb5846cfe77716e77673443ab0e6;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/compiler/basicTypes/UniqSupply.lhs b/compiler/basicTypes/UniqSupply.lhs index 41ad5c0..2599d8d 100644 --- a/compiler/basicTypes/UniqSupply.lhs +++ b/compiler/basicTypes/UniqSupply.lhs @@ -1,9 +1,16 @@ % +% (c) The University of Glasgow 2006 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % -\section[UniqSupply]{The @UniqueSupply@ data type and a (monadic) supply thereof} \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module UniqSupply ( UniqSupply, -- Abstractly @@ -11,26 +18,28 @@ module UniqSupply ( uniqFromSupply, uniqsFromSupply, -- basic ops UniqSM, -- type: unique supply monad - initUs, initUs_, thenUs, thenUs_, returnUs, fixUs, getUs, withUs, - getUniqueUs, getUniquesUs, - mapUs, mapAndUnzipUs, mapAndUnzip3Us, - thenMaybeUs, mapAccumLUs, + initUs, initUs_, lazyThenUs, lazyMapUs, + module MonadUtils, mapAndUnzipM, + MonadUnique(..), mkSplitUniqSupply, - splitUniqSupply + splitUniqSupply, listSplitUniqSupply ) where #include "HsVersions.h" import Unique +import FastTypes -import GLAEXTS -import UNSAFE_IO ( unsafeInterleaveIO ) +#if __GLASGOW_HASKELL__ >= 607 +import GHC.IOBase (unsafeDupableInterleaveIO) +#else +import System.IO.Unsafe ( unsafeInterleaveIO ) +unsafeDupableInterleaveIO :: IO a -> IO a +unsafeDupableInterleaveIO = unsafeInterleaveIO +#endif -w2i x = word2Int# x -i2w x = int2Word# x -i2w_s x = (x :: Int#) \end{code} @@ -47,7 +56,7 @@ which will be distinct from the first and from all others. \begin{code} data UniqSupply - = MkSplitUniqSupply Int -- make the Unique with this + = MkSplitUniqSupply FastInt -- make the Unique with this UniqSupply UniqSupply -- when split => these two supplies \end{code} @@ -56,42 +65,37 @@ data UniqSupply mkSplitUniqSupply :: Char -> IO UniqSupply splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply) +listSplitUniqSupply :: UniqSupply -> [UniqSupply] -- Infinite uniqFromSupply :: UniqSupply -> Unique uniqsFromSupply :: UniqSupply -> [Unique] -- Infinite \end{code} \begin{code} -mkSplitUniqSupply (C# c#) - = let -#if __GLASGOW_HASKELL__ >= 503 - mask# = (i2w (ord# c#)) `uncheckedShiftL#` (i2w_s 24#) -#else - mask# = (i2w (ord# c#)) `shiftL#` (i2w_s 24#) -#endif +mkSplitUniqSupply c + = case fastOrd (cUnbox c) `shiftLFastInt` _ILIT(24) of + mask -> let -- here comes THE MAGIC: -- This is one of the most hammered bits in the whole compiler - mk_supply# - = unsafeInterleaveIO ( - mk_unique >>= \ uniq -> - mk_supply# >>= \ s1 -> - mk_supply# >>= \ s2 -> - return (MkSplitUniqSupply uniq s1 s2) - ) - - mk_unique = genSymZh >>= \ (W# u#) -> - return (I# (w2i (mask# `or#` u#))) - in - mk_supply# - -foreign import ccall unsafe "genSymZh" genSymZh :: IO Word + mk_supply + = unsafeDupableInterleaveIO ( + genSymZh >>= \ u_ -> case iUnbox u_ of { u -> ( + mk_supply >>= \ s1 -> + mk_supply >>= \ s2 -> + return (MkSplitUniqSupply (mask `bitOrFastInt` u) s1 s2) + )}) + in + mk_supply + +foreign import ccall unsafe "genSymZh" genSymZh :: IO Int splitUniqSupply (MkSplitUniqSupply _ s1 s2) = (s1, s2) +listSplitUniqSupply (MkSplitUniqSupply _ s1 s2) = s1 : listSplitUniqSupply s2 \end{code} \begin{code} -uniqFromSupply (MkSplitUniqSupply n _ _) = mkUniqueGrimily n -uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily n : uniqsFromSupply s2 +uniqFromSupply (MkSplitUniqSupply n _ _) = mkUniqueGrimily (iBox n) +uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily (iBox n) : uniqsFromSupply s2 \end{code} %************************************************************************ @@ -101,14 +105,19 @@ uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily n : uniqsFromSupply %************************************************************************ \begin{code} -type UniqSM result = UniqSupply -> (result, UniqSupply) +newtype UniqSM result = USM { unUSM :: UniqSupply -> (result, UniqSupply) } + +instance Monad UniqSM where + return = returnUs + (>>=) = thenUs + (>>) = thenUs_ -- the initUs function also returns the final UniqSupply; initUs_ drops it initUs :: UniqSupply -> UniqSM a -> (a,UniqSupply) -initUs init_us m = case m init_us of { (r,us) -> (r,us) } +initUs init_us m = case unUSM m init_us of { (r,us) -> (r,us) } initUs_ :: UniqSupply -> UniqSM a -> a -initUs_ init_us m = case m init_us of { (r,us) -> r } +initUs_ init_us m = case unUSM m init_us of { (r,us) -> r } {-# INLINE thenUs #-} {-# INLINE lazyThenUs #-} @@ -118,48 +127,61 @@ initUs_ init_us m = case m init_us of { (r,us) -> r } @thenUs@ is where we split the @UniqSupply@. \begin{code} -fixUs :: (a -> UniqSM a) -> UniqSM a -fixUs m us - = (r,us') where (r,us') = m r us +instance MonadFix UniqSM where + mfix m = USM (\us -> let (r,us') = unUSM (m r) us in (r,us')) thenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b -thenUs expr cont us - = case (expr us) of { (result, us') -> cont result us' } +thenUs (USM expr) cont + = USM (\us -> case (expr us) of + (result, us') -> unUSM (cont result) us') lazyThenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b -lazyThenUs expr cont us - = let (result, us') = expr us in cont result us' +lazyThenUs (USM expr) cont + = USM (\us -> let (result, us') = expr us in unUSM (cont result) us') thenUs_ :: UniqSM a -> UniqSM b -> UniqSM b -thenUs_ expr cont us - = case (expr us) of { (_, us') -> cont us' } - +thenUs_ (USM expr) (USM cont) + = USM (\us -> case (expr us) of { (_, us') -> cont us' }) returnUs :: a -> UniqSM a -returnUs result us = (result, us) +returnUs result = USM (\us -> (result, us)) withUs :: (UniqSupply -> (a, UniqSupply)) -> UniqSM a -withUs f us = f us -- Ha ha! +withUs f = USM (\us -> f us) -- Ha ha! getUs :: UniqSM UniqSupply -getUs us = splitUniqSupply us +getUs = USM (\us -> splitUniqSupply us) + +-- | A monad for generating unique identifiers +class Monad m => MonadUnique m where + -- | Get a new UniqueSupply + getUniqueSupplyM :: m UniqSupply + -- | Get a new unique identifier + getUniqueM :: m Unique + -- | Get an infinite list of new unique identifiers + getUniquesM :: m [Unique] + + getUniqueM = liftM uniqFromSupply getUniqueSupplyM + getUniquesM = liftM uniqsFromSupply getUniqueSupplyM + +instance MonadUnique UniqSM where + getUniqueSupplyM = USM (\us -> splitUniqSupply us) + getUniqueM = getUniqueUs + getUniquesM = getUniquesUs getUniqueUs :: UniqSM Unique -getUniqueUs us = case splitUniqSupply us of - (us1,us2) -> (uniqFromSupply us1, us2) +getUniqueUs = USM (\us -> case splitUniqSupply us of + (us1,us2) -> (uniqFromSupply us1, us2)) getUniquesUs :: UniqSM [Unique] -getUniquesUs us = case splitUniqSupply us of - (us1,us2) -> (uniqsFromSupply us1, us2) +getUniquesUs = USM (\us -> case splitUniqSupply us of + (us1,us2) -> (uniqsFromSupply us1, us2)) \end{code} \begin{code} -mapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b] -mapUs f [] = returnUs [] -mapUs f (x:xs) - = f x `thenUs` \ r -> - mapUs f xs `thenUs` \ rs -> - returnUs (r:rs) +{-# -- SPECIALIZE mapM :: (a -> UniqSM b) -> [a] -> UniqSM [b] #-} +{-# -- SPECIALIZE mapAndUnzipM :: (a -> UniqSM (b,c)) -> [a] -> UniqSM ([b],[c]) #-} +{-# -- SPECIALIZE mapAndUnzip3M :: (a -> UniqSM (b,c,d)) -> [a] -> UniqSM ([b],[c],[d]) #-} lazyMapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b] lazyMapUs f [] = returnUs [] @@ -168,36 +190,4 @@ lazyMapUs f (x:xs) lazyMapUs f xs `lazyThenUs` \ rs -> returnUs (r:rs) -mapAndUnzipUs :: (a -> UniqSM (b,c)) -> [a] -> UniqSM ([b],[c]) -mapAndUnzip3Us :: (a -> UniqSM (b,c,d)) -> [a] -> UniqSM ([b],[c],[d]) - -mapAndUnzipUs f [] = returnUs ([],[]) -mapAndUnzipUs f (x:xs) - = f x `thenUs` \ (r1, r2) -> - mapAndUnzipUs f xs `thenUs` \ (rs1, rs2) -> - returnUs (r1:rs1, r2:rs2) - -mapAndUnzip3Us f [] = returnUs ([],[],[]) -mapAndUnzip3Us f (x:xs) - = f x `thenUs` \ (r1, r2, r3) -> - mapAndUnzip3Us f xs `thenUs` \ (rs1, rs2, rs3) -> - returnUs (r1:rs1, r2:rs2, r3:rs3) - -thenMaybeUs :: UniqSM (Maybe a) -> (a -> UniqSM (Maybe b)) -> UniqSM (Maybe b) -thenMaybeUs m k - = m `thenUs` \ result -> - case result of - Nothing -> returnUs Nothing - Just x -> k x - -mapAccumLUs :: (acc -> x -> UniqSM (acc, y)) - -> acc - -> [x] - -> UniqSM (acc, [y]) - -mapAccumLUs f b [] = returnUs (b, []) -mapAccumLUs f b (x:xs) - = f b x `thenUs` \ (b__2, x__2) -> - mapAccumLUs f b__2 xs `thenUs` \ (b__3, xs__2) -> - returnUs (b__3, x__2:xs__2) \end{code}