home *** CD-ROM | disk | FTP | other *** search
- ----------------------------------------------------------------
- -- This is a simple implementation of Cordy Hall's assertions
- -- (for performance debugging).
- --
- -- NB These primitives are an _experimental_ feature which may be
- -- removed in future versions of Hugs.
- -- They can only be used if hugs was configured with the
- -- "--enable-internal-prims" flag.
- --
- -- These primitives mostly break referential transparency - but you're
- -- only supposed to use them for debugging purposes.
- ----------------------------------------------------------------
-
- module CVHAssert(
- Test, Action,
- assert,
- isEvaluated,
- pointerEqual
- ) where
-
- import HugsInternals(
- ptrEq,
- Name, nameInfo,
- Cell, getCell, cellPtrEq,
- CellKind(..), classifyCell,
- )
- import IOExts(
- unsafePerformIO
- )
-
- ----------------------------------------------------------------
- -- High level operations
- ----------------------------------------------------------------
-
- type Test a = a -> Bool
- type Action a = a -> IO ()
-
- assert :: Test a -> Action a -> a -> a
- assert test action x =
- unsafePerformIO (if test x then return () else action x)
- `seq`
- x
-
- isEvaluated :: a -> Bool
- isEvaluated x = unsafePerformIO (
- isEvaluatedCell (getCell x)
- )
-
- representationSize :: a -> Int
- representationSize x = unsafePerformIO (do
- cells <- cellsOf (getCell x) []
- return (cellSize * length cells)
- )
-
- pointerEqual :: a -> a -> Bool
- pointerEqual = ptrEq
-
- ----------------------------------------------------------------
- -- Utilities
- ----------------------------------------------------------------
-
- isEvaluatedCell :: Cell -> IO Bool
- isEvaluatedCell cell = do
- kind <- classifyCell False cell
-
- case kind of
- Apply fun args -> do
- funkind <- classifyCell False fun
- case funkind of
- Fun nm -> return (nameArity nm > length args)
- _ -> return True
- _ -> return True
-
- arityOf :: Cell -> IO Int
- arityOf cell = do
- kind <- classifyCell False cell
-
- case kind of
- Apply fun args -> do
- funarity <- arityOf fun
- return (funarity - length args)
-
- Fun nm -> return (nameArity nm)
- Con nm -> return (nameArity nm)
- Tuple i -> return i
- _ -> return 0
-
-
- nameArity :: Name -> Int
- nameArity nm = case nameInfo nm of (arity,_,_) -> arity
-
- -- list cells occurring in Cell
- cellsOf :: Cell -> [Cell] -> IO [Cell]
-
- cellsOf cell seen
- | cell `elemCell` seen
- = return seen
- | otherwise
- = do
- let seen' = cell:seen
-
- kind <- classifyCell False cell
-
- case kind of
- Apply f xs -> do
- seen'' <- cellsOf f seen'
- cellsOf' xs seen''
- Fun _ -> return seen'
- Con _ -> return seen'
- Tuple _ -> return seen'
- Int _ -> return seen'
- Integer _ -> return seen'
- Float _ -> return seen'
- Char _ -> return seen'
- Prim _ -> return seen'
- Error _ -> return seen' -- we could argue about this one
-
- cellsOf' :: [Cell] -> [Cell] -> IO [Cell]
- cellsOf' [] seen = return seen
- cellsOf' (x:xs) seen = do seen' <- cellsOf x seen
- cellsOf' xs seen'
-
- elemCell :: Cell -> [Cell] -> Bool
- x `elemCell` [] = False
- x `elemCell` (y:ys) = x `cellPtrEq` y || x `elemCell` ys
-
- cellSize :: Int
- cellSize = 8
-
- ----------------------------------------------------------------
-