8d86582efeecf878b8d77c3ce1ec7a9c8a57b06f
[ghc-hetmet.git] / compiler / main / BreakArray.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Break Arrays in the IO monad
4 -- Entries in the array are Word sized 
5 --
6 -- (c) The University of Glasgow 2007
7 --
8 -----------------------------------------------------------------------------
9
10 {-# OPTIONS -w #-}
11 -- The above warning supression flag is a temporary kludge.
12 -- While working on this module you are encouraged to remove it and fix
13 -- any warnings in the module. See
14 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
15 -- for details
16
17 module BreakArray
18   ( BreakArray (BA)
19         -- constructor is exported only for ByteCodeGen
20   , newBreakArray
21   , getBreak 
22   , setBreakOn 
23   , setBreakOff
24   , showBreakArray
25   ) where
26
27 import GHC.Exts
28 import GHC.IOBase
29 import GHC.Word
30 import Constants
31
32 data BreakArray = BA (MutableByteArray# RealWorld)
33
34 breakOff, breakOn :: Word
35 breakOn  = 1
36 breakOff = 0
37
38 -- XXX crude
39 showBreakArray :: BreakArray -> IO ()
40 showBreakArray array = do
41    let loop count sz
42           | count == sz = return ()
43           | otherwise = do
44                val <- readBreakArray array count 
45                putStr $ " " ++ show val
46                loop (count + 1) sz
47    loop 0 (size array) 
48    putStr "\n"
49
50 setBreakOn :: BreakArray -> Int -> IO Bool 
51 setBreakOn array index
52    | safeIndex array index = do 
53         writeBreakArray array index breakOn 
54         return True
55    | otherwise = return False 
56
57 setBreakOff :: BreakArray -> Int -> IO Bool 
58 setBreakOff array index
59    | safeIndex array index = do
60         writeBreakArray array index breakOff
61         return True
62    | otherwise = return False 
63
64 getBreak :: BreakArray -> Int -> IO (Maybe Word)
65 getBreak array index 
66    | safeIndex array index = do
67         val <- readBreakArray array index 
68         return $ Just val 
69    | otherwise = return Nothing
70
71 safeIndex :: BreakArray -> Int -> Bool
72 safeIndex array index = index < size array && index >= 0
73
74 size :: BreakArray -> Int
75 size (BA array) = (I# (sizeofMutableByteArray# array)) `div` wORD_SIZE
76
77 allocBA :: Int -> IO BreakArray 
78 allocBA (I# sz) = IO $ \s1 ->
79   case newByteArray# sz s1 of { (# s2, array #) -> (# s2, BA array #) }
80
81 -- create a new break array and initialise elements to zero
82 newBreakArray :: Int -> IO BreakArray
83 newBreakArray entries@(I# sz) = do
84    BA array <- allocBA (entries * wORD_SIZE) 
85    case breakOff of 
86       W# off -> do    -- Todo: there must be a better way to write zero as a Word!
87          let loop n
88                 | n ==# sz = return ()
89                 | otherwise = do
90                      writeBA# array n off 
91                      loop (n +# 1#)
92          loop 0#
93    return $ BA array
94
95 writeBA# :: MutableByteArray# RealWorld -> Int# -> Word# -> IO ()
96 writeBA# array i word = IO $ \s ->
97   case writeWordArray# array i word s of { s -> (# s, () #) }
98
99 writeBreakArray :: BreakArray -> Int -> Word -> IO ()
100 writeBreakArray (BA array) (I# i) (W# word) = writeBA# array i word 
101
102 readBA# :: MutableByteArray# RealWorld -> Int# -> IO Word 
103 readBA# array i = IO $ \s -> 
104    case readWordArray# array i s of { (# s, c #) -> (# s, W# c #) }
105
106 readBreakArray :: BreakArray -> Int -> IO Word 
107 readBreakArray (BA array) (I# i) = readBA# array i