module VM.Instruction.Index
( instJump
, instJumpIfFalse
, instJumpIfTrue
) where
import Control.Monad.State.Strict (modify)
import VM.VMState (VirtualMachine, VMState(..))
import VM.VMValue (VMValue(..))
import VM.Bytecode.Reader (readInt32)
import VM.VMStack (stackPop)
import Common.Type.Integer (intValueToInt)
isTruth :: VMValue -> Bool
isTruth :: VMValue -> Bool
isTruth (VBool Bool
b) = Bool
b
isTruth (VInt IntValue
i) = IntValue -> Int
intValueToInt IntValue
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
isTruth VMValue
_ = Bool
False
instJump :: VirtualMachine ()
instJump :: VirtualMachine ()
instJump = do
offset <- VirtualMachine Int
readInt32
modify $ \VMState
vm -> VMState
vm { bytecodeIndex = bytecodeIndex vm + offset }
instJumpIfFalse :: VirtualMachine ()
instJumpIfFalse :: VirtualMachine ()
instJumpIfFalse = do
offset <- VirtualMachine Int
readInt32
v <- stackPop
case isTruth v of
Bool
False ->
(VMState -> VMState) -> VirtualMachine ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((VMState -> VMState) -> VirtualMachine ())
-> (VMState -> VMState) -> VirtualMachine ()
forall a b. (a -> b) -> a -> b
$ \VMState
vm -> VMState
vm { bytecodeIndex = bytecodeIndex vm + offset }
Bool
True -> () -> VirtualMachine ()
forall a. a -> StateT VMState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
instJumpIfTrue :: VirtualMachine ()
instJumpIfTrue :: VirtualMachine ()
instJumpIfTrue = do
offset <- VirtualMachine Int
readInt32
v <- stackPop
case isTruth v of
Bool
True ->
(VMState -> VMState) -> VirtualMachine ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((VMState -> VMState) -> VirtualMachine ())
-> (VMState -> VMState) -> VirtualMachine ()
forall a b. (a -> b) -> a -> b
$ \VMState
vm -> VMState
vm { bytecodeIndex = bytecodeIndex vm + offset }
Bool
False -> () -> VirtualMachine ()
forall a. a -> StateT VMState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()