module VM.Bytecode.Reader
( readByte
, readInt8
, readWord8
, readInt16
, readWord16
, readInt32
, readWord32
, readInt64
, readWord64
) where
import Control.Monad.State.Strict (get, put)
import Data.Bits ((.|.), shiftL)
import qualified Data.ByteString as BS
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Word (Word8, Word16, Word32, Word64)
import VM.VMState (VMState(..), VirtualMachine)
readByte :: VirtualMachine Word8
readByte :: VirtualMachine Word8
readByte = do
vm <- StateT VMState IO VMState
forall s (m :: * -> *). MonadState s m => m s
get
let code = VMState -> ByteString
bytecode VMState
vm
let idx = VMState -> Int
bytecodeIndex VMState
vm
case idx >= BS.length code of
Bool
True ->
[Char] -> VirtualMachine Word8
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: Unexpected End of Bytecode (Segmentation Fault)"
Bool
False -> VMState -> StateT VMState IO ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (VMState
vm { bytecodeIndex = idx + 1 }) StateT VMState IO ()
-> VirtualMachine Word8 -> VirtualMachine Word8
forall a b.
StateT VMState IO a -> StateT VMState IO b -> StateT VMState IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
Word8 -> VirtualMachine Word8
forall a. a -> StateT VMState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
code Int
idx)
readWord8 :: VirtualMachine Word8
readWord8 :: VirtualMachine Word8
readWord8 = VirtualMachine Word8
readByte
readInt8 :: VirtualMachine Int8
readInt8 :: VirtualMachine Int8
readInt8 = Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int8) -> VirtualMachine Word8 -> VirtualMachine Int8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VirtualMachine Word8
readByte
readWord16 :: VirtualMachine Word16
readWord16 :: VirtualMachine Word16
readWord16 = do
b1 <- Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word16) -> VirtualMachine Word8 -> VirtualMachine Word16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VirtualMachine Word8
readByte
b2 <- fromIntegral <$> readByte
return $ (b1 `shiftL` 8) .|. b2
readInt16 :: VirtualMachine Int16
readInt16 :: VirtualMachine Int16
readInt16 = Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int16) -> VirtualMachine Word16 -> VirtualMachine Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VirtualMachine Word16
readWord16
readWord32 :: VirtualMachine Word32
readWord32 :: VirtualMachine Word32
readWord32 = do
b1 <- Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word32) -> VirtualMachine Word8 -> VirtualMachine Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VirtualMachine Word8
readByte
b2 <- fromIntegral <$> readByte
b3 <- fromIntegral <$> readByte
b4 <- fromIntegral <$> readByte
return $ (b1 `shiftL` 24) .|. (b2 `shiftL` 16) .|. (b3 `shiftL` 8) .|. b4
readInt32 :: VirtualMachine Int
readInt32 :: VirtualMachine Int
readInt32 = do
w32 <- VirtualMachine Word32
readWord32
return (fromIntegral (fromIntegral w32 :: Int32))
readWord64 :: VirtualMachine Word64
readWord64 :: VirtualMachine Word64
readWord64 = do
b1 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> VirtualMachine Word8 -> VirtualMachine Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VirtualMachine Word8
readByte; b2 <- fromIntegral <$> readByte
b3 <- fromIntegral <$> readByte; b4 <- fromIntegral <$> readByte
b5 <- fromIntegral <$> readByte; b6 <- fromIntegral <$> readByte
b7 <- fromIntegral <$> readByte; b8 <- fromIntegral <$> readByte
return $ (b1 `shiftL` 56) .|. (b2 `shiftL` 48) .|. (b3 `shiftL` 40) .|.
(b4 `shiftL` 32) .|. (b5 `shiftL` 24) .|. (b6 `shiftL` 16) .|.
(b7 `shiftL` 8) .|. b8
readInt64 :: VirtualMachine Int64
readInt64 :: VirtualMachine Int64
readInt64 = Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int64) -> VirtualMachine Word64 -> VirtualMachine Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VirtualMachine Word64
readWord64