module VM.VMStack
( stackPush
, stackPop
, stackTop
) where
import Control.Monad.State.Strict (get, put, modify)
import qualified Data.Vector as V
import VM.VMState (VMState(..), VirtualMachine)
import VM.VMValue (VMValue)
stackPush :: VMValue -> VirtualMachine ()
stackPush :: VMValue -> VirtualMachine ()
stackPush VMValue
val = (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
s -> VMState
s { vStack = V.snoc (vStack s) val }
stackPop :: VirtualMachine VMValue
stackPop :: VirtualMachine VMValue
stackPop = do
s <- StateT VMState IO VMState
forall s (m :: * -> *). MonadState s m => m s
get
case V.null (vStack s) of
Bool
True -> [Char] -> VirtualMachine VMValue
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: Stack Underflow"
Bool
False -> VMState -> VirtualMachine ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (VMState
s { vStack = V.init (vStack s) }) VirtualMachine ()
-> VirtualMachine VMValue -> VirtualMachine VMValue
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
>>
VMValue -> VirtualMachine VMValue
forall a. a -> StateT VMState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector VMValue -> VMValue
forall a. Vector a -> a
V.last (VMState -> Vector VMValue
vStack VMState
s))
stackTop :: VirtualMachine VMValue
stackTop :: VirtualMachine VMValue
stackTop = do
s <- StateT VMState IO VMState
forall s (m :: * -> *). MonadState s m => m s
get
case V.null (vStack s) of
Bool
True -> [Char] -> VirtualMachine VMValue
forall a. HasCallStack => [Char] -> a
error [Char]
"VM Error: Stack Underflow (Top)"
Bool
False -> VMValue -> VirtualMachine VMValue
forall a. a -> StateT VMState IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector VMValue -> VMValue
forall a. Vector a -> a
V.last (VMState -> Vector VMValue
vStack VMState
s))