module RetroClash.Stack where

import Clash.Prelude

data Stack n a = Stack (Vec n a) (Index n)
    deriving ((forall x. Stack n a -> Rep (Stack n a) x)
-> (forall x. Rep (Stack n a) x -> Stack n a)
-> Generic (Stack n a)
forall x. Rep (Stack n a) x -> Stack n a
forall x. Stack n a -> Rep (Stack n a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (n :: Nat) a x. Rep (Stack n a) x -> Stack n a
forall (n :: Nat) a x. Stack n a -> Rep (Stack n a) x
$cto :: forall (n :: Nat) a x. Rep (Stack n a) x -> Stack n a
$cfrom :: forall (n :: Nat) a x. Stack n a -> Rep (Stack n a) x
Generic, HasCallStack => String -> Stack n a
Stack n a -> Bool
Stack n a -> ()
Stack n a -> Stack n a
(HasCallStack => String -> Stack n a)
-> (Stack n a -> Bool)
-> (Stack n a -> Stack n a)
-> (Stack n a -> ())
-> NFDataX (Stack n a)
forall a.
(HasCallStack => String -> a)
-> (a -> Bool) -> (a -> a) -> (a -> ()) -> NFDataX a
forall (n :: Nat) a.
(NFDataX a, KnownNat n, HasCallStack) =>
String -> Stack n a
forall (n :: Nat) a. (NFDataX a, KnownNat n) => Stack n a -> Bool
forall (n :: Nat) a. (NFDataX a, KnownNat n) => Stack n a -> ()
forall (n :: Nat) a.
(NFDataX a, KnownNat n) =>
Stack n a -> Stack n a
rnfX :: Stack n a -> ()
$crnfX :: forall (n :: Nat) a. (NFDataX a, KnownNat n) => Stack n a -> ()
ensureSpine :: Stack n a -> Stack n a
$censureSpine :: forall (n :: Nat) a.
(NFDataX a, KnownNat n) =>
Stack n a -> Stack n a
hasUndefined :: Stack n a -> Bool
$chasUndefined :: forall (n :: Nat) a. (NFDataX a, KnownNat n) => Stack n a -> Bool
deepErrorX :: String -> Stack n a
$cdeepErrorX :: forall (n :: Nat) a.
(NFDataX a, KnownNat n, HasCallStack) =>
String -> Stack n a
NFDataX, Int -> Stack n a -> ShowS
[Stack n a] -> ShowS
Stack n a -> String
(Int -> Stack n a -> ShowS)
-> (Stack n a -> String)
-> ([Stack n a] -> ShowS)
-> Show (Stack n a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (n :: Nat) a. Show a => Int -> Stack n a -> ShowS
forall (n :: Nat) a. Show a => [Stack n a] -> ShowS
forall (n :: Nat) a. Show a => Stack n a -> String
showList :: [Stack n a] -> ShowS
$cshowList :: forall (n :: Nat) a. Show a => [Stack n a] -> ShowS
show :: Stack n a -> String
$cshow :: forall (n :: Nat) a. Show a => Stack n a -> String
showsPrec :: Int -> Stack n a -> ShowS
$cshowsPrec :: forall (n :: Nat) a. Show a => Int -> Stack n a -> ShowS
Show)

push :: (KnownNat n) => a -> Stack n a -> Stack n a
push :: a -> Stack n a -> Stack n a
push a
x (Stack Vec n a
xs Index n
i) = Vec n a -> Index n -> Stack n a
forall (n :: Nat) a. Vec n a -> Index n -> Stack n a
Stack (Index n -> a -> Vec n a -> Vec n a
forall (n :: Nat) i a.
(KnownNat n, Enum i) =>
i -> a -> Vec n a -> Vec n a
replace Index n
i a
x Vec n a
xs) (Index n
i Index n -> Index n -> Index n
forall a. Num a => a -> a -> a
+ Index n
1)

pop :: (KnownNat n) => Stack n a -> (a, Stack n a)
pop :: Stack n a -> (a, Stack n a)
pop (Stack Vec n a
xs Index n
i) = (Vec n a
xs Vec n a -> Index n -> a
forall (n :: Nat) i a. (KnownNat n, Enum i) => Vec n a -> i -> a
!! (Index n
i Index n -> Index n -> Index n
forall a. Num a => a -> a -> a
- Index n
1), Vec n a -> Index n -> Stack n a
forall (n :: Nat) a. Vec n a -> Index n -> Stack n a
Stack Vec n a
xs (Index n
i Index n -> Index n -> Index n
forall a. Num a => a -> a -> a
- Index n
1))