Skip to content

Commit

Permalink
Use little endian encoding of ByteStrings in Anoma
Browse files Browse the repository at this point in the history
Anoma decodes integer atoms as bytes assuming a little endian layout.

This commit adds functions byteStringToIntegerLE and
integerToByteStringLE that makes it clear that little endian encoding is
being used.
  • Loading branch information
paulcadman committed May 31, 2024
1 parent cfaa176 commit 0b0b978
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions src/Juvix/Compiler/Nockma/Encoding/ByteString.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module Juvix.Compiler.Nockma.Encoding.ByteString where

import Data.Bit
import Juvix.Compiler.Nockma.Encoding.Base
import Data.Bits
import Data.ByteString qualified as BS
import Data.ByteString.Builder qualified as BS
import Juvix.Compiler.Nockma.Language
import Juvix.Prelude.Base

Expand All @@ -12,33 +13,34 @@ byteStringToAtom :: (NockNatural a, Member (Error (ErrNockNatural a)) r) => Byte
byteStringToAtom = fmap mkEmptyAtom . fromNatural . byteStringToNatural

byteStringToNatural :: ByteString -> Natural
byteStringToNatural = bitsToNatural . cloneFromByteString
byteStringToNatural = fromInteger . byteStringToIntegerLE

naturalToByteString :: Natural -> ByteString
naturalToByteString = cloneToByteString . naturalToBits
naturalToByteString = integerToByteStringLE . toInteger

textToNatural :: Text -> Natural
textToNatural = byteStringToNatural . encodeUtf8
byteStringToIntegerLE :: ByteString -> Integer
byteStringToIntegerLE = BS.foldr (\b acc -> acc `shiftL` 8 .|. fromIntegral b) 0

bitsToNatural :: Vector Bit -> Natural
bitsToNatural = fromInteger . vectorBitsToInteger
integerToByteStringLE :: Integer -> ByteString
integerToByteStringLE = BS.toStrict . BS.toLazyByteString . go
where
go :: Integer -> BS.Builder
go = \case
0 -> mempty
n -> BS.word8 (fromIntegral n) <> go (n `shiftR` 8)

naturalToBits :: Natural -> Vector Bit
naturalToBits = integerToVectorBits . toInteger
textToNatural :: Text -> Natural
textToNatural = byteStringToNatural . encodeUtf8

atomToText :: (NockNatural a, Member (Error (ErrNockNatural a)) r) => Atom a -> Sem r Text
atomToText = fmap decodeUtf8Lenient . atomToByteString

-- | Construct an atom formed by concatenating the bits of two atoms, where each atom represents a sequence of bytes
atomConcatenateBytes :: forall a r. (NockNatural a, Member (Error (ErrNockNatural a)) r) => Atom a -> Atom a -> Sem r (Atom a)
atomConcatenateBytes l r = do
-- cloneToByteString ensures that the bytestring is zero-padded up to the byte boundary
lBs <- cloneToByteString <$> atomToBits l
rBs <- cloneToByteString <$> atomToBits r
lBs <- atomToByteString l
rBs <- atomToByteString r
byteStringToAtom (lBs <> rBs)
where
atomToBits :: Atom a -> Sem r (Vector Bit)
atomToBits = fmap naturalToBits . nockNatural

mkEmptyAtom :: a -> Atom a
mkEmptyAtom x =
Expand Down

0 comments on commit 0b0b978

Please sign in to comment.