{-# OPTIONS --safe --cubical #-}
module Spartan6.Foundation.Hex where
open import Spartan6.Prelude
open import Agda.Builtin.Char using (Char; primCharEquality)
open import Agda.Builtin.String using (primStringToList)
Nibble : Type₀
Nibble = Vec Bit 4
nibble0 nibble1 nibble2 nibble3 : Nibble
nibble0 = low ∷ low ∷ low ∷ low ∷ []
nibble1 = low ∷ low ∷ low ∷ high ∷ []
nibble2 = low ∷ low ∷ high ∷ low ∷ []
nibble3 = low ∷ low ∷ high ∷ high ∷ []
nibble4 nibble5 nibble6 nibble7 : Nibble
nibble4 = low ∷ high ∷ low ∷ low ∷ []
nibble5 = low ∷ high ∷ low ∷ high ∷ []
nibble6 = low ∷ high ∷ high ∷ low ∷ []
nibble7 = low ∷ high ∷ high ∷ high ∷ []
nibble8 nibble9 nibbleA nibbleB : Nibble
nibble8 = high ∷ low ∷ low ∷ low ∷ []
nibble9 = high ∷ low ∷ low ∷ high ∷ []
nibbleA = high ∷ low ∷ high ∷ low ∷ []
nibbleB = high ∷ low ∷ high ∷ high ∷ []
nibbleC nibbleD nibbleE nibbleF : Nibble
nibbleC = high ∷ high ∷ low ∷ low ∷ []
nibbleD = high ∷ high ∷ low ∷ high ∷ []
nibbleE = high ∷ high ∷ high ∷ low ∷ []
nibbleF = high ∷ high ∷ high ∷ high ∷ []
hexDigit : Char → Maybe Nibble
hexDigit char =
if primCharEquality char '0' then just nibble0 else
if primCharEquality char '1' then just nibble1 else
if primCharEquality char '2' then just nibble2 else
if primCharEquality char '3' then just nibble3 else
if primCharEquality char '4' then just nibble4 else
if primCharEquality char '5' then just nibble5 else
if primCharEquality char '6' then just nibble6 else
if primCharEquality char '7' then just nibble7 else
if primCharEquality char '8' then just nibble8 else
if primCharEquality char '9' then just nibble9 else
if primCharEquality char 'a' then just nibbleA else
if primCharEquality char 'A' then just nibbleA else
if primCharEquality char 'b' then just nibbleB else
if primCharEquality char 'B' then just nibbleB else
if primCharEquality char 'c' then just nibbleC else
if primCharEquality char 'C' then just nibbleC else
if primCharEquality char 'd' then just nibbleD else
if primCharEquality char 'D' then just nibbleD else
if primCharEquality char 'e' then just nibbleE else
if primCharEquality char 'E' then just nibbleE else
if primCharEquality char 'f' then just nibbleF else
if primCharEquality char 'F' then just nibbleF else
nothing
nibbleToMSBList : Nibble → List Bit
nibbleToMSBList (b3 ∷ b2 ∷ b1 ∷ b0 ∷ []) =
b3 ∷ᴸ b2 ∷ᴸ b1 ∷ᴸ b0 ∷ᴸ []ᴸ
decodeCharsMSB : List Char → Maybe (List Bit)
decodeCharsMSB []ᴸ = just []ᴸ
decodeCharsMSB (char ∷ᴸ chars) with hexDigit char
... | nothing = nothing
... | just nibble with decodeCharsMSB chars
... | nothing = nothing
... | just bits = just (nibbleToMSBList nibble ++ᴸ bits)
decodeHexMSB : String → Maybe (List Bit)
decodeHexMSB text = decodeCharsMSB (primStringToList text)
reverseOnto : ∀ {ℓ} {A : Type ℓ} → List A → List A → List A
reverseOnto []ᴸ accumulator = accumulator
reverseOnto (value ∷ᴸ values) accumulator =
reverseOnto values (value ∷ᴸ accumulator)
reverseList : ∀ {ℓ} {A : Type ℓ} → List A → List A
reverseList values = reverseOnto values []ᴸ
toVendorINITOrder : List Bit → List Bit
toVendorINITOrder = reverseList
decodeHexINITOrder : String → Maybe (List Bit)
decodeHexINITOrder text with decodeHexMSB text
... | nothing = nothing
... | just bits = just (toVendorINITOrder bits)
listToVecExact : ∀ {ℓ} {A : Type ℓ} (size : ℕ)
→ List A → Maybe (Vec A size)
listToVecExact zero []ᴸ = just []
listToVecExact zero (value ∷ᴸ rest) = nothing
listToVecExact (suc n) []ᴸ = nothing
listToVecExact (suc n) (value ∷ᴸ rest) with listToVecExact n rest
... | nothing = nothing
... | just values = just (value ∷ values)
decodeHexMSBFixed : (bitCount : ℕ) → String → Maybe (Vec Bit bitCount)
decodeHexMSBFixed bitCount text with decodeHexMSB text
... | nothing = nothing
... | just bits = listToVecExact bitCount bits
decodeHexINITFixed : (bitCount : ℕ) → String → Maybe (Vec Bit bitCount)
decodeHexINITFixed bitCount text with decodeHexINITOrder text
... | nothing = nothing
... | just bits = listToVecExact bitCount bits
twoBitINITNibble : Nibble → Maybe (Vec Bit 2)
twoBitINITNibble (b3 ∷ b2 ∷ b1 ∷ b0 ∷ []) =
if b3 or b2
then nothing
else just (b0 ∷ b1 ∷ [])
decodeTwoBitINITChars : List Char → Maybe (Vec Bit 2)
decodeTwoBitINITChars []ᴸ = nothing
decodeTwoBitINITChars (char ∷ᴸ []ᴸ) with hexDigit char
... | nothing = nothing
... | just nibble = twoBitINITNibble nibble
decodeTwoBitINITChars (first ∷ᴸ second ∷ᴸ rest) = nothing
decodeHexINIT2 : String → Maybe (Vec Bit 2)
decodeHexINIT2 text = decodeTwoBitINITChars (primStringToList text)
digit-0 : hexDigit '0' ≡ just (low ∷ low ∷ low ∷ low ∷ [])
digit-0 = refl
digit-1 : hexDigit '1' ≡ just (low ∷ low ∷ low ∷ high ∷ [])
digit-1 = refl
digit-8 : hexDigit '8' ≡ just (high ∷ low ∷ low ∷ low ∷ [])
digit-8 = refl
digit-F : hexDigit 'F' ≡ just (high ∷ high ∷ high ∷ high ∷ [])
digit-F = refl
digit-f : hexDigit 'f' ≡ just (high ∷ high ∷ high ∷ high ∷ [])
digit-f = refl
invalid-digit : hexDigit 'G' ≡ nothing
invalid-digit = refl
multi-digit-MSB :
decodeHexMSB "1A"
≡ just
(low ∷ᴸ low ∷ᴸ low ∷ᴸ high
∷ᴸ high ∷ᴸ low ∷ᴸ high ∷ᴸ low ∷ᴸ []ᴸ)
multi-digit-MSB = refl
multi-digit-INIT-order :
decodeHexINITOrder "1A"
≡ just
(low ∷ᴸ high ∷ᴸ low ∷ᴸ high
∷ᴸ high ∷ᴸ low ∷ᴸ low ∷ᴸ low ∷ᴸ []ᴸ)
multi-digit-INIT-order = refl
fixed-eight-bits :
decodeHexINITFixed 8 "1A"
≡ just (low ∷ high ∷ low ∷ high ∷ high ∷ low ∷ low ∷ low ∷ [])
fixed-eight-bits = refl
fixed-size-rejects-too-many-bits : decodeHexMSBFixed 4 "1A" ≡ nothing
fixed-size-rejects-too-many-bits = refl
two-bit-INIT-zero : decodeHexINIT2 "0" ≡ just (low ∷ low ∷ [])
two-bit-INIT-zero = refl
two-bit-INIT-one : decodeHexINIT2 "1" ≡ just (high ∷ low ∷ [])
two-bit-INIT-one = refl
two-bit-INIT-two : decodeHexINIT2 "2" ≡ just (low ∷ high ∷ [])
two-bit-INIT-two = refl
two-bit-INIT-three : decodeHexINIT2 "3" ≡ just (high ∷ high ∷ [])
two-bit-INIT-three = refl
two-bit-INIT-rejects-high-padding : decodeHexINIT2 "4" ≡ nothing
two-bit-INIT-rejects-high-padding = refl
two-bit-INIT-rejects-two-digits : decodeHexINIT2 "00" ≡ nothing
two-bit-INIT-rejects-two-digits = refl