-- SPDX-FileCopyrightText: 2020 Tocqueville Group -- -- SPDX-License-Identifier: LicenseRef-MIT-TQ -- | General utilities used by interpreter. -- -- This is not supposed to import any Michelson modules. module Michelson.Interpret.Utils ( encodeZarithNumber ) where import Control.Exception (assert) import qualified Data.Bits as Bits -- | Encode a number as tezos does this. -- -- In the Tezos reference implementation this encoding is called @zarith@. encodeZarithNumber :: Integer -> NonEmpty Word8 encodeZarithNumber = doEncode True where {- Numbers, when packed by tezos, are represented as follows: byte 0: 1 _ ______ || lowest digits has continuation is negative payload || || byte 1: 1 _______ || ... 1 _______ || byte n: 0 _______ || has continuation payload \/ highest digits -} doEncode :: Bool -> Integer -> NonEmpty Word8 doEncode isFirst a | a >= byteWeight = let (hi, lo) = a `divMod` byteWeight byte = Bits.setBit (fromIntegral @_ @Word8 lo) 7 in byte :| toList (doEncode False hi) | a >= 0 = one (fromIntegral @_ @Word8 a) | otherwise = assert isFirst $ let h :| t = doEncode True (-a) in Bits.setBit h 6 :| t where byteWeight = if isFirst then 64 else 128