Skip to content

takenobu-hs/ghci-hexcalc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GHCi as a Hex-Calculator interactive

The GHCi (REPL for Haskell) is a very useful interactive tool, it's not only for debugging :)
This package "ghci-hexcalc" is an interactive hex-calculator using Haskell/GHCi. This is a simple and casual tool like Perl and Excel for our 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

See also description on Hackage.

Contents

Run

Bare GHCi:

$ ghci src/Data/GHex.hs

or

$ ghci -ghci-script example/example.ghci

Stack:

$ stack exec -- ghci  src/Data/GHex.hs

Example of use

Numeric literals by Hex type annotation

The value of Hex type is shown as hexadecimal format.

ghci> 1 :: Hex
0x0000_0000_0000_0001
ghci> 0xff :: Hex
0x0000_0000_0000_00ff
ghci> 0b1011 :: Hex
0x0000_0000_0000_000b
ghci> 16 + 3 :: Hex
0x0000_0000_0000_0013

Variables on GHCi

You could use variables of Haskell syntax on GHCi.

ghci> x = 255 :: Hex
ghci> x + 3
ghci> y = it       -- `it` is GHCi's variable. It stores the previous result.

Arithmetic operations

You could also use arithmetic operators in Hex type.

ghci> x + 3
ghci> (x * 256) -1
ghci> x + 2^10
ghci> neg x

Logical operations

Numeric literals applied to functions of this package are inferred as Hex type.

ghci> 0xff .& 6
ghci> 256 .| 16
ghci> 100 .^ 5
ghci> inv 255

Shift operations

ghci> 1 .<< 16
ghci> 256 .>> 1

Div and mod operations

ghci> 0xff0000 ./ 256
ghci> 0xfedc .% 256

Generate bit and byte with position

ghci> bit1 15
0x0000_0000_0000_8000
ghci> bits 7 4
0x0000_0000_0000_00f0
ghci> bitList [15, 14, 1]
0x0000_0000_0000_c002
ghci> byte1 2
0x0000_0000_00ff_0000
ghci> bytes 4 3
0x0000_00ff_ff00_0000

Extract and replace bits

ghci> gets 0xabcd 15 12
0x0000_0000_0000_000a
ghci> puts 0xabcd 15 12 7
0x0000_0000_0000_7bcd

Set and clear bits

ghci> sbits 0x1234 11 8
0x0000_0000_0000_1f34
ghci> cbits 0x1234 7 4
0x0000_0000_0000_1204

Get asserted bit positions and count bits

ghci> pos1 0x0081
[7,0]
ghci> pos0 $ inv 0x0100
[8]
ghci> count1 0b11001
3

Permute, split and merge

ghci> gather 0x12345678 0x0ff000f0
0x0000_0000_0000_0237
ghci> scatter 0x12345678 0xff00ff00 0xabcd
0x0000_0000_ab34_cd78
ghci> (3,0b101) .++ (2,0b11)
(5,0x0000_0000_0000_0017)

Predefined-constants

ghci> mega
0x0000_0000_0010_0000
ghci> giga
0x0000_0000_4000_0000
ghci> 4 * giga - 1
0x0000_0000_ffff_ffff
ghci> 2^32 ./ giga
0x0000_0000_0000_0004

Postfix-notation

The operator .@ is an operator for postfix notation. It's the same as Data.Function.(&).

The following two are the same:

ghci> pos1 0xf0
[7,6,5,4]
ghci> 0xf0 .@pos1
[7,6,5,4]

Formatting for hex, bin, dec, Tera,Giga,Mega,Kilo, signed and floating

Formatting functions convert a Hex type value to a string type for each format.

ghci> 2^16 .@hex
"0x0000_0000_0001_0000"
ghci> 100 .@bin
"0b110_0100"
ghci> 100 .@bin16
"0b0000_0000_0110_0100"
ghci> giga .@dec
"1073741824"
ghci> bit 43 .@decT
"8"
ghci> 0xffffffffffffffff .@signed
"-1"
ghci> 0x3fc00000 .@float
"1.5"

Hilighting specified bits

The function color highlights specified bits. It inverts the color in the ANSI sequence for the specified bits.

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
             ^^                                                            ^ ^^

Input and convert

The function inputRawHexIO inputs a string and converts it to a Hex type.

ghci> inputRawHexIO
ff aa  (your input)
ghci> x = it
ghci> x
0x0000_0000_0000_ffaa
ghci> x <- inputRawHexIO
ff aa  (your input)
ghci> x
0x0000_0000_0000_ffaa

Floating conversion examples

ghci> float2hex 1.0
0x0000_0000_3f80_0000
ghci> hex2float 0x3fc00000
1.5
ghci> double2hex 1.0
0x3ff0_0000_0000_0000
ghci> hex2double 0x40091eb851eb851f
3.14
ghci> splitFloat (-1)
[1,127,0]
ghci> mergeFloat [0, 127, 2^22]
1.5
ghci> splitDouble (-0.5)
[1,1022,0]
ghci> mergeDouble [0, 1023, 2^51]
1.5

Combination examples

ghci> x .| bit1 18
ghci> (x .<< 4) .& 0xf0
ghci> bit1 33 ./ giga
ghci> 2 * mega .@dec
ghci> 4 * tera .@pos1
ghci> foldr1 (.|) [0xa, 0xcc, 0xd1b]
ghci> 0 .@color (tera .| giga .| mega .| kilo)

Using Data.Bits library

Hex type is deriving Data.Bits type. So you could use functions of Data.Bits.

ghci> x `testBit` 8
ghci> x `clearBit` 15
ghci> x .&. 0xff
ghci> x `rotateL` 4
ghci> countLeadingZeros x

Clear screen

ghci> cls

Simple help

Show simple usage:

ghci> usage

Listing APIs with :browse ghci command:

ghci> :browse
newtype Hex = Hex Word
(.&) :: Hex -> Hex -> Hex
(.|) :: Hex -> Hex -> Hex
(.^) :: Hex -> Hex -> Hex
inv :: Hex -> Hex
  :

When you run with ghci -haddock, you could also use :doc ghci command (ghc8.6 or later):

ghci> :doc bits
 Set bits from n1 to n2

 >>> bits 15 8
 0x0000_0000_0000_ff00

Specification

Please see also Hackage document in detail.

General

  • Core type:
    • The core type of this package is the Hex type.
    • Hex type is implemented in unsigned Word.
    • Hex type is 64 bit length on x86_64.
  • Operators and functions:
    • Operators in this package begin with .(dot), like .& and .|.
    • Most functions align bits to the LSB side.

Numeric literals by Hex type annotation

Operation Description
:: Hex Type annotation for basic type Hex
255 :: Hex Decimal number literal
0xff :: Hex Hexadecimal number literal
0b1101 :: Hex binary number literal

Derived operations

Operation Description
Many operations Eq, Ord, Num, Enum, Real, Bounded, Integral, Bits and FiniteBits class available

Postfix operator

Operation Description
.@ Postfix-notation operator

Arithmetic operations

Operation Description
+, -, *, ^, ... Num, Real class available
neg x1 Negation. (inv x1 + 1)
signext x1 n1 Sign extention
x1 ./ x2 Integer division
x1 .% x2 Integer modulo

Logical operations

Operation Description
x1 .& x2 Bitwise "and"
x1 .| x2 Bitwise "or"
x1 .^ x2 Bitwise "xor"
inv x1 Bitwise "not" (invert)

Shift operations

Operation Description
x1 .<< n1 Logical left shift
x1 .>> n1 Logical right shift

Generate bit and byte with position

Operation Description
bit1 n1 Set a bit
bits n1 n2 Set bits from n1 to n2
bitList [n1, n2, ... nn] Set bits with List
byte1 n1 Set a byte
bytes n1 n2 Set bytes from n1 to n2
mask n1 Set bits from 0 to n1

Extract and replace bits

Operation Description
gets x1 n1 n2 Extract bits from n1 to n2
puts x1 n1 n2 x2 Replace bits from n1 to n2
getBit1 x1 n1 Extract bit at n1
getBits x1 n1 n2 Synonym to gets
getByte1 x1 n1 Extract bytes from n1 to 0
getBytes x1 n1 n2 Extract bytes from n1 to n2
putBit1 x1 n1 x2 Replace byte at n1
putBits x1 n1 n2 x2 Synonym to puts
putBytes x1 n1 n2 x2 Replace bytes from n1 to n2

Set and clear bits

Operation Description
sbits x1 n1 n2 Set bits from n1 to n2 of x1
cbits x1 n1 n2 Clear bits from n1 to n2 of x1

Get asserted bit positions and count bits

Operation Description
pos1 x1 Get bit positions asserted with 1
pos0 x1 Get bit positions asserted with 0
range x1 Get upper and lower boundaries
count1 x1 Count bit-1
count0 x1 Count bit-0

Permute

Operation Description
bitrev x1 Reverse bits
byterev x1 Reverse bytes
gather x1 x2 Gather bits from x1 by x2
scatter x1 x2 x3 Scatter bits from x3 to x1 by x2

Split and merge

Operation Description
splitBits x1 Split bits to List
splitBytes x1 Split bytes to List
mergeBits [x1, x2, .. xn] Merge bits from List
mergeBytes [x1, x2, .. xn] Merge bytes from List
splitPairs [n1, .. nn] x1 Split bits to pair of (length,Hex)
mergePairs [(n1,x1),..] Merge bits from pair of (length,Hex)
(n1,x1) .++ (n2,x2) Concatinate pairs of (length,Hex)

Predefined-constants

Constant Description
exa 2^60 (It's not 10^18)
peta 2^50 (It's not 10^15)
tera 2^40 (It's not 10^12)
giga 2^30 (It's not 10^9)
mega 2^20 (It's not 10^6)
kilo 2^10 (It's not 10^3)
zero 0
one 1
all0 0x0
all1 inv all0
hexBitSize 64 on x86_64. Thus size of Word
hexBitSeq [hexBitSize-1, hexBitSize-2, .. 0]

Formatting for hex, bin, dec, Tera,Giga,Mega,Kilo, signed and floating

Operation Description
.@hex Show in hexadecimal string
.@hex8 Show in hexadecimal string of 8bit
.@hex16 Show in hexadecimal string of 16bit
.@hex32 Show in hexadecimal string of 32bit
.@hex64 Show in hexadecimal string of 64bit
.@hexN n1 Show in hexadecimal string of n1 bit
.@hexs Show in hexadecimal string of List
.@bin Show in binary string
.@bin8 Show in binary string of 8bit
.@bin16 Show in binary string of 16bit
.@bin32 Show in binary string of 32bit
.@bin64 Show in binary string of 64bit
.@binN n1 Show in binary string of n1 bit
.@dec Show in decimal string
.@decE Show in decimal of Exa unit
.@decP Show in decimal of Peta unit
.@decT Show in decimal of Tera unit
.@decG Show in decimal of Giga unit
.@decM Show in decimal of Mega unit
.@decK Show in decimal of Kilo unit
.@signed Show in singed decimal with Word
.@float Show in float string
.@double Show in double string
.@hexSized Show in hexadecimal string of (len,Hex)
.@binSized Show in binary string of (len,Hex)

Hilighting and pretty-print

Operation Description
color x1 x2 Highlight bit of x1 specified with x2
ppr fun x1 Print x1 applied with fun

Input and convert

Operation Description
inputRawHexIO Input string and convert to Hex type

Floating convert

Operation Description
float2hex Convert Float to Hex type
hex2float Convert Hex to Float type
double2hex Convert Double to Hex type
hex2double Convert Hex to Double type
splitFloat Split Float to elements
mergeFloat Merge Float from elements
splitDouble Split Double to elements
mergeDouble Merge Double from elements

Miscellaneous

Operation Description
cls Clear screen by ANSI sequence
usage Show simple help

Appendix

GHC language extention for numeric literals

When -XBinaryLiterals extention enabled, you can use binary literals on GHC and GHCi, like 0b1101.

When -XNumericUnderscores extention enabled, you can use underscores in numeric literals on GHC and GHCi, like 0xff_ff. -XNumericUnderscores extension is available GHC 8.6 or later.

GHC language extensions can be described in ~/.ghci or ./ghci file:

:set -XBinaryLiterals
:set -XNumericUnderscores

GHC language extensions can also be specified as an option when starting GHC and GHCi:

$ ghci -XBinaryLiterals -XNumericUnderscores

Shell alias

It is useful to set the alias of the shell:

alias ghex="(cd $XXX/ghci-hexcalc; ghci -ghci-script example/example.ghci)"

Expression evaluation mode of GHC

You can also run in one shot mode (a expression evaluation mod) by ghc -e:

$ ghc src/Data/GHex.hs -e '4 * giga'
0x0000_0004_0000_0000

Default declaration on GHCi

With the default declaration, integer literals are inferred as Hex types.

ghci> default (Hex)
ghci> 255
0x0000_0000_0000_00ff