{- -- EPITECH PROJECT, 2025 -- Glados -- File description: -- Encoder.hs -} {-| Module : Compiler.Encoder Description : Low-level binary encoding utilities for bytecode generation. Stability : stable This module provides helper functions to encode primitive values into binary form using 'Data.ByteString.Builder'. These functions are used by the assembler and encoder stages to produce the final bytecode stream. Supported encodings: - 32-bit signed integers (big-endian) - Single bytes (Word8) - Booleans (encoded as 0 or 1) - UTF-8 strings with length prefix -} module Compiler.Bytecode.Encoder ( encodeInt32BE , encodeWord8 , encodeBool , encodeString ) where import qualified Data.ByteString.Builder as B import qualified Data.ByteString as BS import qualified Data.Text as T import qualified Data.Text.Encoding as TE import Data.Int (Int32) import Data.Word (Word8) -- | Encode a signed 32-bit integer in big-endian format. -- -- This function emits exactly 4 bytes corresponding to the given 'Int32' -- value, encoded in network byte order (big-endian). -- -- It is primarily used for instruction operands such as relative offsets, -- indices, and immediate integer values. encodeInt32BE :: Int32 -> B.Builder encodeInt32BE :: Int32 -> Builder encodeInt32BE = Int32 -> Builder B.int32BE -- | Encode a single byte. -- -- Writes the given 'Word8' value as-is into the output stream. -- This function is typically used to encode opcodes and small immediate -- values. encodeWord8 :: Word8 -> B.Builder encodeWord8 :: Word8 -> Builder encodeWord8 = Word8 -> Builder B.word8 -- | Encode a boolean value as a single byte. -- -- Encoding convention: -- -- * 'True' is encoded as @1@ -- * 'False' is encoded as @0@ -- -- This representation is used consistently throughout the bytecode format. encodeBool :: Bool -> B.Builder encodeBool :: Bool -> Builder encodeBool Bool True = Word8 -> Builder B.word8 Word8 1 encodeBool Bool False = Word8 -> Builder B.word8 Word8 0 -- | Encode a UTF-8 string with a length prefix. -- -- The string is first encoded as UTF-8, then preceded by a 32-bit -- big-endian integer representing the number of bytes in the encoded -- string. -- -- Layout: -- -- > [length: Int32][utf8-bytes...] -- -- This encoding is suitable for constant strings, symbol names, or -- metadata embedded in the bytecode. encodeString :: String -> B.Builder encodeString :: String -> Builder encodeString = ((Int32 -> Builder B.int32BE (Int32 -> Builder) -> (ByteString -> Int32) -> ByteString -> Builder forall b c a. (b -> c) -> (a -> b) -> a -> c . Int -> Int32 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int -> Int32) -> (ByteString -> Int) -> ByteString -> Int32 forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Int BS.length) (ByteString -> Builder) -> (ByteString -> Builder) -> ByteString -> Builder forall a. Semigroup a => a -> a -> a <> ByteString -> Builder B.byteString) (ByteString -> Builder) -> (String -> ByteString) -> String -> Builder forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> ByteString TE.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> Text T.pack