Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use little endian encoding of ByteStrings in Anoma #2793

Merged
merged 1 commit into from
May 31, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading