module Data.BAByNF.Util.Hex
    ( Digit (..)
    , Seq (..)
    , val
    , toNum
    , fromVal
    , toChar
    ) where

data Digit
    = X0
    | X1
    | X2
    | X3
    | X4
    | X5
    | X6
    | X7
    | X8
    | X9
    | XA
    | XB
    | XC
    | XD
    | XE
    | XF
    deriving (Digit -> Digit -> Bool
(Digit -> Digit -> Bool) -> (Digit -> Digit -> Bool) -> Eq Digit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Digit -> Digit -> Bool
== :: Digit -> Digit -> Bool
$c/= :: Digit -> Digit -> Bool
/= :: Digit -> Digit -> Bool
Eq, Eq Digit
Eq Digit =>
(Digit -> Digit -> Ordering)
-> (Digit -> Digit -> Bool)
-> (Digit -> Digit -> Bool)
-> (Digit -> Digit -> Bool)
-> (Digit -> Digit -> Bool)
-> (Digit -> Digit -> Digit)
-> (Digit -> Digit -> Digit)
-> Ord Digit
Digit -> Digit -> Bool
Digit -> Digit -> Ordering
Digit -> Digit -> Digit
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Digit -> Digit -> Ordering
compare :: Digit -> Digit -> Ordering
$c< :: Digit -> Digit -> Bool
< :: Digit -> Digit -> Bool
$c<= :: Digit -> Digit -> Bool
<= :: Digit -> Digit -> Bool
$c> :: Digit -> Digit -> Bool
> :: Digit -> Digit -> Bool
$c>= :: Digit -> Digit -> Bool
>= :: Digit -> Digit -> Bool
$cmax :: Digit -> Digit -> Digit
max :: Digit -> Digit -> Digit
$cmin :: Digit -> Digit -> Digit
min :: Digit -> Digit -> Digit
Ord)
newtype Seq = Seq [Digit] deriving Seq -> Seq -> Bool
(Seq -> Seq -> Bool) -> (Seq -> Seq -> Bool) -> Eq Seq
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Seq -> Seq -> Bool
== :: Seq -> Seq -> Bool
$c/= :: Seq -> Seq -> Bool
/= :: Seq -> Seq -> Bool
Eq

val :: (Integral a) => Digit -> a
val :: forall a. Integral a => Digit -> a
val Digit
X0 = a
0
val Digit
X1 = a
1
val Digit
X2 = a
2
val Digit
X3 = a
3
val Digit
X4 = a
4
val Digit
X5 = a
5
val Digit
X6 = a
6
val Digit
X7 = a
7
val Digit
X8 = a
8
val Digit
X9 = a
9
val Digit
XA = a
10
val Digit
XB = a
11
val Digit
XC = a
12
val Digit
XD = a
13
val Digit
XE = a
14
val Digit
XF = a
15

toNum :: (Integral a) => Seq -> a
toNum :: forall a. Integral a => Seq -> a
toNum (Seq [Digit]
digits) = [Digit] -> a -> a
forall {t}. Integral t => [Digit] -> t -> t
toNum' [Digit]
digits a
0
    where toNum' :: [Digit] -> t -> t
toNum' [] t
acc = t
acc
          toNum' (Digit
d : [Digit]
ds) t
acc = 
            let newAcc :: t
newAcc = (t
acc t -> t -> t
forall a. Num a => a -> a -> a
* t
16) t -> t -> t
forall a. Num a => a -> a -> a
+ Digit -> t
forall a. Integral a => Digit -> a
val Digit
d
             in [Digit] -> t -> t
toNum' [Digit]
ds t
newAcc

fromVal :: (Integral a) => a -> Maybe Digit
fromVal :: forall a. Integral a => a -> Maybe Digit
fromVal a
0 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X0
fromVal a
1 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X1
fromVal a
2 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X2
fromVal a
3 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X3
fromVal a
4 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X4
fromVal a
5 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X5
fromVal a
6 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X6
fromVal a
7 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X7
fromVal a
8 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X8
fromVal a
9 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
X9
fromVal a
10 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
XA
fromVal a
11 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
XB
fromVal a
12 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
XC
fromVal a
13 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
XD
fromVal a
14 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
XE
fromVal a
15 = Digit -> Maybe Digit
forall a. a -> Maybe a
Just Digit
XF
fromVal a
_ = Maybe Digit
forall a. Maybe a
Nothing

instance Show Seq where
    show :: Seq -> String
show (Seq [Digit]
x) = (Digit -> Char) -> [Digit] -> String
forall a b. (a -> b) -> [a] -> [b]
map Digit -> Char
toChar [Digit]
x

toChar :: Digit -> Char
toChar :: Digit -> Char
toChar Digit
d = case Digit
d of
    Digit
X0 -> Char
'0'
    Digit
X1 -> Char
'1'
    Digit
X2 -> Char
'2'
    Digit
X3 -> Char
'3'
    Digit
X4 -> Char
'4'
    Digit
X5 -> Char
'5'
    Digit
X6 -> Char
'6'
    Digit
X7 -> Char
'7'
    Digit
X8 -> Char
'8'
    Digit
X9 -> Char
'9'
    Digit
XA -> Char
'A'
    Digit
XB -> Char
'B'
    Digit
XC -> Char
'C'
    Digit
XD -> Char
'D'
    Digit
XE -> Char
'E'
    Digit
XF -> Char
'F'