module VM.Instruction.Stack
( instPush
, instPop
, instDup
, instSwap
, instCast
, instTypeOf
, instSizeOf
) where
import Data.Word (Word8)
import qualified Data.Vector as V
import Common.Type.Integer (IntValue(..))
import VM.VMState (VirtualMachine)
import VM.VMValue
( VMValue(..)
, castValue
, getValueName
, stringToValue
)
import VM.Bytecode.Reader
( readByte
, readInt8
, readWord8
, readInt16
, readWord16
, readInt32
, readWord32
, readInt64
, readWord64
)
import VM.VMStack
( stackPush
, stackPop
, stackTop
)
stackPushValue :: Word8 -> VirtualMachine ()
stackPushValue :: Word8 -> VirtualMachine ()
stackPushValue Word8
0x00 = do v <- VirtualMachine Word8
readByte; stackPush (VBool (v /= 0))
stackPushValue Word8
0x01 = do v <- VirtualMachine Int8
readInt8; stackPush (VInt (I8 v))
stackPushValue Word8
0x02 = do v <- VirtualMachine Word8
readWord8; stackPush (VInt (UI8 v))
stackPushValue Word8
0x03 = do v <- VirtualMachine Int16
readInt16; stackPush (VInt (I16 v))
stackPushValue Word8
0x04 = do v <- VirtualMachine Word16
readWord16; stackPush (VInt (UI16 v))
stackPushValue Word8
0x05 = do
v <- VirtualMachine Int
readInt32
stackPush (VInt (I32 (fromIntegral v)))
stackPushValue Word8
0x06 = do v <- VirtualMachine Word32
readWord32; stackPush (VInt (UI32 v))
stackPushValue Word8
0x07 = do v <- VirtualMachine Int64
readInt64; stackPush (VInt (I64 v))
stackPushValue Word8
0x08 = do v <- VirtualMachine Word64
readWord64; stackPush (VInt (UI64 v))
stackPushValue Word8
0x09 = do v <- VirtualMachine Int8
readInt8; stackPush (VInt (IChar v))
stackPushValue Word8
0x10 = do v <- VirtualMachine Word8
readWord8; stackPush (VInt (UIChar v))
stackPushValue Word8
t = [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> VirtualMachine ()) -> [Char] -> VirtualMachine ()
forall a b. (a -> b) -> a -> b
$ [Char]
"VM Error: Unsupported PUSH TypeID: 0x" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Word8 -> [Char]
forall a. Show a => a -> [Char]
show Word8
t
instPush :: VirtualMachine ()
instPush :: VirtualMachine ()
instPush = do
typeId <- VirtualMachine Word8
readByte
stackPushValue typeId
instPop :: VirtualMachine ()
instPop :: VirtualMachine ()
instPop = do
_ <- VirtualMachine VMValue
stackPop
return ()
instDup :: VirtualMachine ()
instDup :: VirtualMachine ()
instDup = do
v <- VirtualMachine VMValue
stackTop
stackPush v
instSwap :: VirtualMachine ()
instSwap :: VirtualMachine ()
instSwap = do
b <- VirtualMachine VMValue
stackPop
a <- stackPop
stackPush b
stackPush a
instCast :: VirtualMachine ()
instCast :: VirtualMachine ()
instCast = do
typeId <- VirtualMachine Word8
readByte
v <- stackPop
stackPush (castValue typeId v)
instTypeOf :: VirtualMachine ()
instTypeOf :: VirtualMachine ()
instTypeOf = do
v <- VirtualMachine VMValue
stackPop
let typeVal = VMValue -> Text
getValueName VMValue
v
stackPush (stringToValue typeVal)
instSizeOf :: VirtualMachine ()
instSizeOf :: VirtualMachine ()
instSizeOf = do
v <- VirtualMachine VMValue
stackPop
case v of
VList Vector VMValue
vec -> VMValue -> VirtualMachine ()
stackPush (IntValue -> VMValue
VInt (Int64 -> IntValue
I64 (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector VMValue -> Int
forall a. Vector a -> Int
V.length Vector VMValue
vec))))
VStruct Vector VMValue
vec -> VMValue -> VirtualMachine ()
stackPush (IntValue -> VMValue
VInt (Int64 -> IntValue
I64 (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector VMValue -> Int
forall a. Vector a -> Int
V.length Vector VMValue
vec))))
VMValue
_ -> [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: sizeof expects a List or Struct"