Copyright | (c) 2018 Takenobu Tani |
---|---|
License | BSD3 |
Maintainer | Takenobu Tani <takenobu.hs@gmail.com> |
Stability | experimental |
Portability | non-portable (GHC Extensions) |
Safe Haskell | None |
Language | Haskell2010 |
- Basic data type
- Logical operations
- Arithmetic operations
- Shift operations
- Generate bits and bytes with position
- Extract and replace bits
- Set and clear bits
- Get asserted bit positions and count bits
- Permute
- Split and merge
- Predefined-constants
- Postfix notation
- Formatting for hex, bin, dec and etc.
- Hilighting and pretty-print
- Input and convert
- Miscellaneous
- Properties
This module defines operations for an interactive hex-caluclator using GHCi. This is a simple and casual interactive tool like Perl and Excel for daily work.
Interactive oriented features:
- Short-named operators and functions
- Show values in hexadecimal format by default
- Suppress type annotation of numeric literals by type inference
- Postfix-notation available
- Highlight available
Example of use:
ghci> (1 .<< 16) .| 0xf .& 3 0x0000_0000_0001_0003
ghci> 0xff .@dec "255"
See also web page.
Synopsis
- data Hex
- (.&) :: Hex -> Hex -> Hex
- (.|) :: Hex -> Hex -> Hex
- (.^) :: Hex -> Hex -> Hex
- inv :: Hex -> Hex
- (./) :: Hex -> Hex -> Hex
- (.%) :: Hex -> Hex -> Hex
- neg :: Hex -> Hex
- signext :: Hex -> Int -> Hex
- (.<<) :: Hex -> Int -> Hex
- (.>>) :: Hex -> Int -> Hex
- bit1 :: Int -> Hex
- bits :: Int -> Int -> Hex
- bitList :: [Int] -> Hex
- byte1 :: Int -> Hex
- bytes :: Int -> Int -> Hex
- mask :: Int -> Hex
- gets :: Hex -> Int -> Int -> Hex
- puts :: Hex -> Int -> Int -> Hex -> Hex
- getBit1 :: Hex -> Int -> Hex
- getByte1 :: Hex -> Int -> Hex
- getBits :: Hex -> Int -> Int -> Hex
- getBytes :: Hex -> Int -> Int -> Hex
- putBit1 :: Hex -> Int -> Hex -> Hex
- putBits :: Hex -> Int -> Int -> Hex -> Hex
- putBytes :: Hex -> Int -> Int -> Hex -> Hex
- sbits :: Hex -> Int -> Int -> Hex
- cbits :: Hex -> Int -> Int -> Hex
- pos1 :: Hex -> [Int]
- pos0 :: Hex -> [Int]
- range1 :: Hex -> (Int, Int)
- count1 :: Hex -> Int
- count0 :: Hex -> Int
- bitrev :: Hex -> Hex
- byterev :: Hex -> Hex
- gather :: Hex -> Hex -> Hex
- scatter :: Hex -> Hex -> Hex -> Hex
- splitBits :: Hex -> [Int]
- splitBytes :: Hex -> [Int]
- mergeBits :: [Int] -> Hex
- mergeBytes :: [Int] -> Hex
- splitSized :: [Int] -> Hex -> [(Int, Hex)]
- mergeSized :: [(Int, Hex)] -> Hex
- (.++) :: (Int, Hex) -> (Int, Hex) -> (Int, Hex)
- exa :: Hex
- peta :: Hex
- tera :: Hex
- giga :: Hex
- mega :: Hex
- kilo :: Hex
- zero :: Hex
- one :: Hex
- all0 :: Hex
- all1 :: Hex
- hexBitSize :: Int
- hexBitSeq :: [Int]
- hexByteSize :: Int
- hexByteSeq :: [Int]
- (.@) :: a -> (a -> b) -> b
- hex :: Hex -> String
- hexN :: Int -> Hex -> String
- hex8 :: Hex -> String
- hex16 :: Hex -> String
- hex32 :: Hex -> String
- hex64 :: Hex -> String
- bin :: Hex -> String
- binN :: Int -> Hex -> String
- bin8 :: Hex -> String
- bin16 :: Hex -> String
- bin32 :: Hex -> String
- bin64 :: Hex -> String
- dec :: Hex -> String
- decE :: Hex -> String
- decP :: Hex -> String
- decT :: Hex -> String
- decG :: Hex -> String
- decM :: Hex -> String
- decK :: Hex -> String
- signed :: Hex -> String
- strip :: String -> String -> String
- hexSized :: (Int, Hex) -> String
- binSized :: (Int, Hex) -> String
- color :: Hex -> Hex -> IO ()
- ppr :: (Hex -> String) -> Hex -> IO ()
- inputRawHexIO :: IO Hex
- cls :: IO ()
- usage :: IO ()
Basic data type
Basic type
>>>
255 :: Hex
0x0000_0000_0000_00ff
Instances
Bounded Hex Source # | |
Enum Hex Source # | |
Eq Hex Source # | |
Integral Hex Source # | |
Num Hex Source # | |
Ord Hex Source # | |
Read Hex Source # | |
Real Hex Source # | |
Defined in Data.GHex toRational :: Hex -> Rational # | |
Show Hex Source # | |
Bits Hex Source # | |
Defined in Data.GHex | |
FiniteBits Hex Source # | |
Defined in Data.GHex |
Logical operations
Arithmetic operations
signext :: Hex -> Int -> Hex Source #
Sign extention
>>>
signext 0x80 7
0xffff_ffff_ffff_ff80>>>
signext 0x7fff 15
0x0000_0000_0000_7fff
Shift operations
(.>>) :: Hex -> Int -> Hex infixl 8 Source #
Logical right shift
>>>
0x0f00 .>> 4
0x0000_0000_0000_00f0
Generate bits and bytes with position
Extract and replace bits
gets :: Hex -> Int -> Int -> Hex Source #
Extract bits from n1 to n2
>>>
gets 0xabcd 15 12
0x0000_0000_0000_000a
puts :: Hex -> Int -> Int -> Hex -> Hex Source #
Replace bits from n1 to n2
>>>
puts 0xabcd 15 12 0b111
0x0000_0000_0000_7bcd
getBytes :: Hex -> Int -> Int -> Hex Source #
Extract bytes from n1 to n2
>>>
getBytes 0x12345678 2 1
0x0000_0000_0000_3456
putBytes :: Hex -> Int -> Int -> Hex -> Hex Source #
Replace bytes from n1 to n2
>>>
putBytes 0x12345678 3 2 0xfedc
0x0000_0000_fedc_5678
Set and clear bits
sbits :: Hex -> Int -> Int -> Hex Source #
Set bits from n1 to n2 of x1
>>>
sbits 0x1234 11 8
0x0000_0000_0000_1f34
cbits :: Hex -> Int -> Int -> Hex Source #
Clear bits from n1 to n2 of x1
>>>
cbits 0x1234 7 4
0x0000_0000_0000_1204
Get asserted bit positions and count bits
range1 :: Hex -> (Int, Int) Source #
Get upper and lower boundaries of asserted bits
>>>
range1 0x0f000000
(27,24)
Permute
gather :: Hex -> Hex -> Hex Source #
Gather bits
>>>
gather 0x12345678 0x0ff000f0
0x0000_0000_0000_0237
scatter :: Hex -> Hex -> Hex -> Hex Source #
Scatter bits
>>>
scatter 0x12345678 0xff00ff00 0xabcd
0x0000_0000_ab34_cd78
Split and merge
splitBits :: Hex -> [Int] Source #
Split bits to List
>>>
splitBits 0xa
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0]
splitBytes :: Hex -> [Int] Source #
Split bytes to List
>>>
splitBytes 0xff10
[0,0,0,0,0,0,255,16]
mergeBits :: [Int] -> Hex Source #
Merge bits from List
>>>
mergeBits [1,0,1,0,0,0,0,0]
0x0000_0000_0000_00a0
mergeBytes :: [Int] -> Hex Source #
Merge bytes from List
>>>
mergeBytes [0xff, 0x1, 0xa]
0x0000_0000_00ff_010a
splitSized :: [Int] -> Hex -> [(Int, Hex)] Source #
Split bits to pair of (length,Hex)
>>>
splitSized [2,4,4] 0xabcd
[(2,0x0000_0000_0000_0003),(4,0x0000_0000_0000_000c),(4,0x0000_0000_0000_000d)]
mergeSized :: [(Int, Hex)] -> Hex Source #
Merge bits from pair of (length,Hex)
>>>
mergeSized [(2,0x3),(4,0xc),(4,0xd)]
0x0000_0000_0000_03cd
(.++) :: (Int, Hex) -> (Int, Hex) -> (Int, Hex) infixl 5 Source #
Concatinate pairs of (length,Hex)
>>>
(3,0b101) .++ (2,0b11)
(5,0x0000_0000_0000_0017)>>>
(4,0xa) .++ (4,0xb) .++ (8,0xcd)
(16,0x0000_0000_0000_abcd)>>>
(4,0xe) .++ (4,0xf) .@snd
0x0000_0000_0000_00ef
Predefined-constants
Unit constants
Ei, Pi, Ti, Gi, Mi and Ki. It's not E(10^18), ... K(10^3).
>>>
exa == 2^60
True>>>
peta == 2^50
True>>>
tera == 2^40
True>>>
giga == 2^30
True>>>
mega == 2^20
True>>>
kilo == 2^10
True
Utility constants
Several constants are also predefined.
>>>
zero
0x0000_0000_0000_0000>>>
one
0x0000_0000_0000_0001>>>
all0
0x0000_0000_0000_0000>>>
all1
0xffff_ffff_ffff_ffff
These can be also used for type inference.
>>>
256*3-1 + zero
0x0000_0000_0000_02ff
Implementation constants
Implementation information of size.
hexBitSize :: Int Source #
Bit size of Hex type. It's 64 on x86_64.
hexByteSize :: Int Source #
Byte size of Hex type. It's 8 of x86_64.
hexByteSeq :: [Int] Source #
Number sequence. [hexByteSeq-1, hexByteSeq-2, .. 0]
Postfix notation
(.@) :: a -> (a -> b) -> b infixl 0 Source #
Operator for postfix notation (same as Data.Function.(&))
>>>
255 .@hex
"0x0000_0000_0000_00ff">>>
0xf1 .@bin
"0b1111_0001">>>
2^12 .@dec
"4096">>>
4 * giga .@pos1
[32]
0x0 .@color (bits 31 24) 0b0000_0000_0000_0000_0000_0000_0000_0000_1111_1111_0000_0000_0000_0000_0000_0000 ^^^^ ^^^^
Formatting for hex, bin, dec and etc.
Formatting utilities.
>>>
255 .@hex
"0x0000_0000_0000_00ff">>>
255 .@bin
"0b1111_1111">>>
0xff .@dec
"255"
>>>
2^32 .@decG
"4"
>>>
map (hexN 12) [0..3]
["0x000","0x001","0x002","0x003"]
>>>
0xffffffffffffffff .@signed
"-1"
>>>
strip "0b" "0b1101"
"1101">>>
strip "_" "0x1234_5678_9abc_def0"
"0x123456789abcdef0"
Hexadecimal formatting
Binary formatting
Decimal formatting
Miscellaneous formatting
Sized data formatting for (length,Hex)
hexSized :: (Int, Hex) -> String Source #
Hexadecimal formatting for pair of (length,Hex)
>>>
(8,254) .@hexSized
"0xfe"
binSized :: (Int, Hex) -> String Source #
Binary formatting for pair of (length,Hex)
>>>
(8,0x71) .@binSized
"0b0111_0001"
Hilighting and pretty-print
color :: Hex -> Hex -> IO () Source #
Highlight the specified bit
ghci> 0xff .@color (bits 7 4) 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1111_1111 ^^^^
ghci> 0xffffffff .@color mega 0b0000_0000_0000_0000_0000_0000_0000_0000_1111_1111_1111_1111_1111_1111_1111_1111 ^
ghci> 0 .@color (bitList [54,53,4,3,2]) 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000 ^^ ^ ^^
ppr :: (Hex -> String) -> Hex -> IO () Source #
Output value by IO (not String)
>>>
0xf0 .@ppr bin
0b1111_0000
Input and convert
inputRawHexIO :: IO Hex Source #
Input hexadecimal string and convert to Hex type
It reads only hexadecimal characters, [0-9a-fA-F].
That is, other characters, such as ',',:
,-
, are ignored.
It is useful for reading from various command output, such as od,
hexdump and etc.
ghci> inputRawHexIO ff aa (your input) ghci>x = it ghci>x 0x0000_0000_0000_ffaa
ghci> inputRawHexIO 0123:abcd:ffff (your input) ghci>x = it ghci>x 0x0000_0123_abcd_ffff
Miscellaneous
Properties
Properties for QuickCheck testing
(inv $ inv x) == x
(neg $ neg x) == x
(neg x) == (inv x + 1)
(x .& y) == (inv ((inv x) .| (inv y))) -- De Morgan
(x .^ y) == (((x .& (inv y)) .| ((inv x) .& y))) -- xor
(y /= 0) ==> ((x ./ y)*y + (x .% y)) == x -- div and mod
(n >= 0) ==> (x .<< n) == (x * (2^n)) -- left shift
(n >= 0) ==> (x .>> n) == (bitrev ((bitrev x) .<< n)) -- right shift
(x >= 0) ==> (bit1 x) == (2^x)
(x >= 0) ==> (byte1 x) == (0xff .<< (8*x))
(x1 >= x2 && x2 >= 0) ==> (bits x1 x2) == (sum $ map (2^) [x2..x1])
(x1 >= x2 && x2 >= 0) ==> (bytes x1 x2) == (sum $ map byte1 [x2..x1])
(x1 >= x2 && x2 >= 0) ==> (gets all0 x1 x2) == all0
(x1 >= x2 && x2 >= 0) ==> ((gets x x1 x2) .<< x2) == (x .& bits x1 x2)
(x1 >= x2 && x2 >= 0) ==> (puts x x1 x2 $ gets x x1 x2) == x
(x1 >= x2 && x2 >= 0) ==> (gather x (bits x1 x2)) == (gets x x1 x2)
(x1 > x2 && x2 >= 0) ==> (gather x3 (bit1 x1 .| bit1 x2)) == (((getBit1 x3 x1) .<< 1) .| (getBit1 x3 x2))
(x1 >= x2 && x2 >= 0) ==> (scatter x1 x2 $ gather x1 x2) == x1
(x1 >= x2 && x2 >= 0) ==> (sbits all0 x1 x2) == (bits x1 x2)
(x1 >= x2 && x2 >= 0) ==> (sbits all0 x1 x2) == (puts all0 x1 x2 all1)
(x1 >= x2 && x2 >= 0) ==> (cbits all1 x1 x2) == (inv(bits x1 x2))
(x1 >= x2 && x2 >= 0) ==> (cbits all1 x1 x2) == (puts all1 x1 x2 all0)
(x1 >= x2 && x2 >= 0) ==> (cbits x x1 x2) == (inv (sbits (inv x) x1 x2))
(x .@pos1 .@bitList) == x
(x .@pos0 .@bitList) == (inv x)
(x1 >= x2 && x2 >= 0 && x1 < hexBitSize) ==> (range1 $ bits x1 x2) == (x1,x2)
(count1 x) == (length $ pos1 x)
((count1 x) + (count0 x)) == hexBitSize
(mergeBits $ splitBits x) == x
(mergeBytes $ splitBytes x) == x
(bitrev $ bitrev x) == x
(byterev $ byterev x) == x
(a1 >= 1 && a2 >= 1 && (a1+a2) <= hexBitSize) ==> ((a1,x1) .++ (a2,x2)) == ((a1+a2), (mergeBits $ (lastN a1 $ splitBits x1) ++ (lastN a2 $ splitBits x2)))
(a1 >= 1 && a2 >= 1 && (a1+a2) <= hexBitSize) ==> ((a1,x1) .++ (a2,x2)) == ((a1+a2), (mergeSized [(a1,x1),(a2,x2)]))
(a1 >= 1 && a2 >= 1 && (a1+a2) <= hexBitSize) ==> (mergeSized $ splitSized [a1,a2] x1) == (x1 .& (mask (a1+a2-1)))
(n >= 0 && x `testBit` n) ==> ((signext x n) .| (sbits x (n-1) 0)) == all1
(n >= 0 && (not(x `testBit` n))) ==> ((signext x n) .& (cbits x (n-1) 0)) == all0
(not(x `testBit` (hexBitSize-1))) ==> (signed x) == (dec x)
(x `testBit` (hexBitSize-1)) ==> (signed x) == show(-1 * (fromIntegral $ ((inv x) + 1))::Int)