symbol 0.1.4 → 0.2.0
raw patch · 4 files changed
+85/−68 lines, 4 filesdep ~base
Dependency ranges changed: base
Files
- Data/Symbol.hs +5/−63
- Data/Symbol/Unsafe.hs +74/−0
- LICENSE +2/−2
- symbol.cabal +4/−3
Data/Symbol.hs view
@@ -1,74 +1,16 @@ -- | -- Module : Data.Symbol--- Copyright : (c) Harvard University 2009-2012--- : (c) Geoffrey Mainland 2011-2012+-- Copyright : (c) Harvard University 2009-2011+-- : (c) Geoffrey Mainland 2011-2013 -- License : BSD-style -- Maintainer : mainland@eecs.harvard.edu -{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE Trustworthy #-} module Data.Symbol (- Symbol(..),+ Symbol, intern, unintern ) where -import Control.Concurrent.MVar-import Control.DeepSeq-import Data.Generics (Data, Typeable)-#if __GLASGOW_HASKELL__ >= 608-import Data.String-#endif /* __GLASGOW_HASKELL__ >= 608 */-import qualified Data.Map as Map-import System.IO.Unsafe (unsafePerformIO)--data Symbol = -- | Unique identifier and the string itself- Symbol {-# UNPACK #-} !Int !String-#if defined(__GLASGOW_HASKELL__)- deriving (Data, Typeable)-#endif /* defined(__GLASGOW_HASKELL__) */--instance Eq Symbol where- (Symbol i1 _) == (Symbol i2 _) = i1 == i2--instance Ord Symbol where- compare (Symbol i1 _) (Symbol i2 _) = compare i1 i2--instance Show Symbol where- showsPrec _ (Symbol _ s) = showString s--#if __GLASGOW_HASKELL__ >= 608-instance IsString Symbol where- fromString = intern-#endif /* __GLASGOW_HASKELL__ >= 608 */--data SymbolEnv = SymbolEnv- { uniq :: {-# UNPACK #-} !Int- , symbols :: !(Map.Map String Symbol)- }--symbolEnv :: MVar SymbolEnv-{-# NOINLINE symbolEnv #-}-symbolEnv = unsafePerformIO $ newMVar $ SymbolEnv 1 Map.empty---- We @seq@ @s@ so that we can guarantee that when we perform the lookup we--- won't potentially have to evaluate a thunk that might itself call @intern@,--- leading to a deadlock.---- |Intern a string to produce a 'Symbol'.-intern :: String -> Symbol-{-# NOINLINE intern #-}-intern s = s `deepseq` unsafePerformIO $ modifyMVar symbolEnv $ \env -> do- case Map.lookup s (symbols env) of- Nothing -> do let sym = Symbol (uniq env) s- let env' = env { uniq = uniq env + 1,- symbols = Map.insert s sym- (symbols env)- }- env' `seq` return (env', sym)- Just sym -> return (env, sym)---- |Return the 'String' associated with a 'Symbol'.-unintern :: Symbol -> String-unintern (Symbol _ s) = s+import Data.Symbol.Unsafe
+ Data/Symbol/Unsafe.hs view
@@ -0,0 +1,74 @@+-- |+-- Module : Data.Symbol.Unsafe+-- Copyright : (c) Harvard University 2009-2011+-- : (c) Geoffrey Mainland 2011-2013+-- License : BSD-style+-- Maintainer : mainland@eecs.harvard.edu++{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}++module Data.Symbol.Unsafe (+ Symbol(..),+ intern,+ unintern+ ) where++import Control.Concurrent.MVar+import Control.DeepSeq+import Data.Generics (Data, Typeable)+#if __GLASGOW_HASKELL__ >= 608+import Data.String+#endif /* __GLASGOW_HASKELL__ >= 608 */+import qualified Data.Map as Map+import System.IO.Unsafe (unsafePerformIO)++data Symbol = -- | Unique identifier and the string itself+ Symbol {-# UNPACK #-} !Int !String+#if defined(__GLASGOW_HASKELL__)+ deriving (Data, Typeable)+#endif /* defined(__GLASGOW_HASKELL__) */++instance Eq Symbol where+ (Symbol i1 _) == (Symbol i2 _) = i1 == i2++instance Ord Symbol where+ compare (Symbol i1 _) (Symbol i2 _) = compare i1 i2++instance Show Symbol where+ showsPrec _ (Symbol _ s) = showString s++#if __GLASGOW_HASKELL__ >= 608+instance IsString Symbol where+ fromString = intern+#endif /* __GLASGOW_HASKELL__ >= 608 */++data SymbolEnv = SymbolEnv+ { uniq :: {-# UNPACK #-} !Int+ , symbols :: !(Map.Map String Symbol)+ }++symbolEnv :: MVar SymbolEnv+{-# NOINLINE symbolEnv #-}+symbolEnv = unsafePerformIO $ newMVar $ SymbolEnv 1 Map.empty++-- We @'deepseq' s@ so that we can guarantee that when we perform the lookup we+-- won't potentially have to evaluate a thunk that might itself call @'intern'@,+-- leading to a deadlock.++-- |Intern a string to produce a 'Symbol'.+intern :: String -> Symbol+{-# NOINLINE intern #-}+intern s = s `deepseq` unsafePerformIO $ modifyMVar symbolEnv $ \env -> do+ case Map.lookup s (symbols env) of+ Nothing -> do let sym = Symbol (uniq env) s+ let env' = env { uniq = uniq env + 1,+ symbols = Map.insert s sym+ (symbols env)+ }+ env' `seq` return (env', sym)+ Just sym -> return (env, sym)++-- |Return the 'String' associated with a 'Symbol'.+unintern :: Symbol -> String+unintern (Symbol _ s) = s
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2006-2010+Copyright (c) 2006-2011 The President and Fellows of Harvard College. Redistribution and use in source and binary forms, with or without@@ -25,7 +25,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Copyright (c) 2011-2012, Geoffrey Mainland+Copyright (c) 2011-2013, Geoffrey Mainland All rights reserved. Redistribution and use in source and binary forms, with or without modification,
symbol.cabal view
@@ -1,10 +1,10 @@ name: symbol-version: 0.1.4+version: 0.2.0 cabal-version: >= 1.6 license: BSD3 license-file: LICENSE-copyright: (c) 2006-2010 Harvard University- (c) 2011-2012 Geoffrey Mainland+copyright: (c) 2006-2011 Harvard University+ (c) 2011-2013 Geoffrey Mainland author: Geoffrey Mainland <mainland@eecs.harvard.edu> maintainer: mainland@eecs.harvard.edu stability: alpha@@ -20,6 +20,7 @@ library exposed-modules: Data.Symbol+ Data.Symbol.Unsafe build-depends: base >= 4 && < 5,