individual operations.
\begin{code}
+{-# OPTIONS -fno-implicit-prelude #-}
+#include "MachDeps.h"
+
module PrelBits where
#ifdef __GLASGOW_HASKELL__
-- Removing all fixities is a fairly safe fix; fixing the "one fixity
-- per symbol per program" limitation in Hugs would take a lot longer.
#ifndef __HUGS__
-infixl 8 `shift`, `rotate`
+infixl 8 `shift`, `rotate`, `shiftL`, `shiftR`, `rotateL`, `rotateR`
infixl 7 .&.
infixl 6 `xor`
infixl 5 .|.
#endif
class Num a => Bits a where
- (.&.), (.|.), xor :: a -> a -> a
- complement :: a -> a
- shift :: a -> Int -> a
- rotate :: a -> Int -> a
- bit :: Int -> a
- setBit :: a -> Int -> a
- clearBit :: a -> Int -> a
- complementBit :: a -> Int -> a
- testBit :: a -> Int -> Bool
- bitSize :: a -> Int
- isSigned :: a -> Bool
-
- bit i = shift 0x1 i
- setBit x i = x .|. bit i
- clearBit x i = x .&. complement (bit i)
- complementBit x i = x `xor` bit i
- testBit x i = (x .&. bit i) /= 0
+ (.&.), (.|.), xor :: a -> a -> a
+ complement :: a -> a
+ shift :: a -> Int -> a
+ rotate :: a -> Int -> a
+ bit :: Int -> a
+ setBit :: a -> Int -> a
+ clearBit :: a -> Int -> a
+ complementBit :: a -> Int -> a
+ testBit :: a -> Int -> Bool
+ bitSize :: a -> Int
+ isSigned :: a -> Bool
+
+ bit i = 1 `shift` i
+ x `setBit` i = x .|. bit i
+ x `clearBit` i = x .&. complement (bit i)
+ x `complementBit` i = x `xor` bit i
+ x `testBit` i = (x .&. bit i) /= 0
shiftL, shiftR :: Bits a => a -> Int -> a
rotateL, rotateR :: Bits a => a -> Int -> a
-shiftL a i = shift a i
-shiftR a i = shift a (-i)
-rotateL a i = rotate a i
-rotateR a i = rotate a (-i)
+x `shiftL` i = x `shift` i
+x `shiftR` i = x `shift` (-i)
+x `rotateL` i = x `rotate` i
+x `rotateR` i = x `rotate` (-i)
+
+instance Bits Int where
+ (I# x#) .&. (I# y#) = I# (word2Int# (int2Word# x# `and#` int2Word# y#))
+ (I# x#) .|. (I# y#) = I# (word2Int# (int2Word# x# `or#` int2Word# y#))
+ (I# x#) `xor` (I# y#) = I# (word2Int# (int2Word# x# `xor#` int2Word# y#))
+ complement (I# x#) = I# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
+ (I# x#) `shift` (I# i#)
+ | i# ==# 0# = I# x#
+ | i# >=# wsib = 0
+ | i# ># 0# = I# (x# `uncheckedIShiftL#` i#)
+ | i# <=# nwsib = I# (if x# <# 0# then -1# else 0#)
+ | otherwise = I# (x# `uncheckedIShiftRA#` negateInt# i#)
+ where
+ wsib = WORD_SIZE_IN_BITS# {- work around preprocessor problem (??) -}
+ nwsib = negateInt# wsib
+ (I# x#) `rotate` (I# i#) =
+ I# (word2Int# ((x'# `uncheckedShiftL#` i'#) `or#`
+ (x'# `uncheckedShiftRL#` (wsib -# i'#))))
+ where
+ x'# = int2Word# x#
+ i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#))
+ wsib = WORD_SIZE_IN_BITS#
+ bitSize _ = WORD_SIZE_IN_BITS
+ isSigned _ = True
\end{code}