module VM.Instruction.Logic
( instEq
, instTEq
, instLt
, instLe
, instNot
, instAnd
, instOr
) where
import VM.VMState (VirtualMachine)
import VM.VMValue (VMValue(..), eqValue)
import VM.VMStack (stackPush, stackPop)
import Common.Type.Integer (intValueToInt)
instNot :: VirtualMachine ()
instNot :: VirtualMachine ()
instNot = do
v <- VirtualMachine VMValue
stackPop
case v of
VBool Bool
b -> VMValue -> VirtualMachine ()
stackPush (Bool -> VMValue
VBool (Bool -> Bool
not Bool
b))
VMValue
_ -> [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: NOT expects Boolean"
instAnd :: VirtualMachine ()
instAnd :: VirtualMachine ()
instAnd = do
v2 <- VirtualMachine VMValue
stackPop
v1 <- stackPop
case (v1, v2) of
(VBool Bool
b1, VBool Bool
b2) -> VMValue -> VirtualMachine ()
stackPush (Bool -> VMValue
VBool (Bool
b1 Bool -> Bool -> Bool
&& Bool
b2))
(VMValue, VMValue)
_ -> [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: AND expects Booleans"
instOr :: VirtualMachine ()
instOr :: VirtualMachine ()
instOr = do
v2 <- VirtualMachine VMValue
stackPop
v1 <- stackPop
case (v1, v2) of
(VBool Bool
b1, VBool Bool
b2) -> VMValue -> VirtualMachine ()
stackPush (Bool -> VMValue
VBool (Bool
b1 Bool -> Bool -> Bool
|| Bool
b2))
(VMValue, VMValue)
_ -> [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: OR expects Booleans"
instEq :: VirtualMachine ()
instEq :: VirtualMachine ()
instEq = do
v2 <- VirtualMachine VMValue
stackPop
v1 <- stackPop
stackPush (VBool (eqValue v1 v2))
instTEq :: VirtualMachine ()
instTEq :: VirtualMachine ()
instTEq = do
v2 <- VirtualMachine VMValue
stackPop
v1 <- stackPop
stackPush (VBool (v1 == v2))
instLt :: VirtualMachine ()
instLt :: VirtualMachine ()
instLt = do
v2 <- VirtualMachine VMValue
stackPop
v1 <- stackPop
case (v1, v2) of
(VInt IntValue
i1, VInt IntValue
i2) -> VMValue -> VirtualMachine ()
stackPush (Bool -> VMValue
VBool (
IntValue -> Int
intValueToInt IntValue
i1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< IntValue -> Int
intValueToInt IntValue
i2))
(VMValue, VMValue)
_ -> [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: LT expects Integers"
instLe :: VirtualMachine ()
instLe :: VirtualMachine ()
instLe = do
v2 <- VirtualMachine VMValue
stackPop
v1 <- stackPop
case (v1, v2) of
(VInt IntValue
i1, VInt IntValue
i2) -> VMValue -> VirtualMachine ()
stackPush (Bool -> VMValue
VBool (
IntValue -> Int
intValueToInt IntValue
i1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= IntValue -> Int
intValueToInt IntValue
i2))
(VMValue, VMValue)
_ -> [Char] -> VirtualMachine ()
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: LE expects Integers"