{-# LANGUAGE MagicHash #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-} -- Any moved from GHC.Prim to GHC.Types -- so import both and use unused imports to get compatibility module Debug.Variables( Var, varId, varShow, Variables, listVariables, newVariables, addVariable ) where import GHC.Types import GHC.Prim import Data.List.Extra import Control.Exception import System.IO.Unsafe import Unsafe.Coerce data Variables = Variables Int -- Number in the array [(Any, String)] -- Entries, (key a, show a), indexed from [n..0] data Var = Var Int String -- index into Variables, show a instance Show Var where show (Var i s) = s ++ " @" ++ show i varId :: Var -> Int varId (Var x _) = x varShow :: Var -> String varShow (Var _ x) = x newVariables :: Variables newVariables = Variables 0 [] listVariables :: Variables -> [Var] listVariables (Variables n xs) = [Var i s | (i,(_,s)) <- zipFrom 0 $ reverse xs] addVariable :: Show a => a -> Variables -> (Variables, Var) addVariable a vs@(Variables n xs) = case findIndex (\(key,_) -> ptrEqual key keyA) xs of Nothing -> (Variables (n+1) ((keyA,showA):xs), Var n showA) Just i -> (vs, Var (n-i-1) $ snd $ xs !! i) where keyA = unsafeCoerce a showA = show a ptrEqual :: Any -> Any -> Bool ptrEqual a b = unsafePerformIO $ do a <- evaluate a b <- evaluate b return (tagToEnum# (reallyUnsafePtrEquality# a b) :: Bool)