module Language.Parser.Ptera.Machine.SRB where

import           Language.Parser.Ptera.Prelude

import qualified Data.EnumMap.Strict                        as EnumMap
import qualified Language.Parser.Ptera.Data.Alignable       as Alignable
import qualified Language.Parser.Ptera.Data.Alignable.Array as AlignableArray
import qualified Language.Parser.Ptera.Data.Symbolic.IntMap as SymbolicIntMap
import qualified Language.Parser.Ptera.Machine.LAPEG        as LAPEG
import qualified Language.Parser.Ptera.Machine.PEG          as PEG


type T = SRB

data SRB start varDoc altDoc a = SRB
    { SRB start varDoc altDoc a -> EnumMap start StateNum
initials :: EnumMap.EnumMap start StateNum
    , SRB start varDoc altDoc a -> T StateNum MState
states   :: AlignableArray.T StateNum MState
    , SRB start varDoc altDoc a -> T AltNum (Alt altDoc a)
alts     :: AlignableArray.T LAPEG.AltNum (LAPEG.Alt altDoc a)
    , SRB start varDoc altDoc a -> T VarNum (Var varDoc)
vars     :: AlignableArray.T LAPEG.VarNum (PEG.Var varDoc)
    }
    deriving (SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool
(SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool)
-> (SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool)
-> Eq (SRB start varDoc altDoc a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall start varDoc altDoc a.
(Eq a, Eq altDoc, Eq varDoc) =>
SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool
/= :: SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool
$c/= :: forall start varDoc altDoc a.
(Eq a, Eq altDoc, Eq varDoc) =>
SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool
== :: SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool
$c== :: forall start varDoc altDoc a.
(Eq a, Eq altDoc, Eq varDoc) =>
SRB start varDoc altDoc a -> SRB start varDoc altDoc a -> Bool
Eq, Int -> SRB start varDoc altDoc a -> ShowS
[SRB start varDoc altDoc a] -> ShowS
SRB start varDoc altDoc a -> String
(Int -> SRB start varDoc altDoc a -> ShowS)
-> (SRB start varDoc altDoc a -> String)
-> ([SRB start varDoc altDoc a] -> ShowS)
-> Show (SRB start varDoc altDoc a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall start varDoc altDoc a.
(Enum start, Show start, Show a, Show altDoc, Show varDoc) =>
Int -> SRB start varDoc altDoc a -> ShowS
forall start varDoc altDoc a.
(Enum start, Show start, Show a, Show altDoc, Show varDoc) =>
[SRB start varDoc altDoc a] -> ShowS
forall start varDoc altDoc a.
(Enum start, Show start, Show a, Show altDoc, Show varDoc) =>
SRB start varDoc altDoc a -> String
showList :: [SRB start varDoc altDoc a] -> ShowS
$cshowList :: forall start varDoc altDoc a.
(Enum start, Show start, Show a, Show altDoc, Show varDoc) =>
[SRB start varDoc altDoc a] -> ShowS
show :: SRB start varDoc altDoc a -> String
$cshow :: forall start varDoc altDoc a.
(Enum start, Show start, Show a, Show altDoc, Show varDoc) =>
SRB start varDoc altDoc a -> String
showsPrec :: Int -> SRB start varDoc altDoc a -> ShowS
$cshowsPrec :: forall start varDoc altDoc a.
(Enum start, Show start, Show a, Show altDoc, Show varDoc) =>
Int -> SRB start varDoc altDoc a -> ShowS
Show, a -> SRB start varDoc altDoc b -> SRB start varDoc altDoc a
(a -> b) -> SRB start varDoc altDoc a -> SRB start varDoc altDoc b
(forall a b.
 (a -> b) -> SRB start varDoc altDoc a -> SRB start varDoc altDoc b)
-> (forall a b.
    a -> SRB start varDoc altDoc b -> SRB start varDoc altDoc a)
-> Functor (SRB start varDoc altDoc)
forall a b.
a -> SRB start varDoc altDoc b -> SRB start varDoc altDoc a
forall a b.
(a -> b) -> SRB start varDoc altDoc a -> SRB start varDoc altDoc b
forall start varDoc altDoc a b.
a -> SRB start varDoc altDoc b -> SRB start varDoc altDoc a
forall start varDoc altDoc a b.
(a -> b) -> SRB start varDoc altDoc a -> SRB start varDoc altDoc b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SRB start varDoc altDoc b -> SRB start varDoc altDoc a
$c<$ :: forall start varDoc altDoc a b.
a -> SRB start varDoc altDoc b -> SRB start varDoc altDoc a
fmap :: (a -> b) -> SRB start varDoc altDoc a -> SRB start varDoc altDoc b
$cfmap :: forall start varDoc altDoc a b.
(a -> b) -> SRB start varDoc altDoc a -> SRB start varDoc altDoc b
Functor)

newtype StateNum = StateNum Int
    deriving (StateNum -> StateNum -> Bool
(StateNum -> StateNum -> Bool)
-> (StateNum -> StateNum -> Bool) -> Eq StateNum
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StateNum -> StateNum -> Bool
$c/= :: StateNum -> StateNum -> Bool
== :: StateNum -> StateNum -> Bool
$c== :: StateNum -> StateNum -> Bool
Eq, Int -> StateNum -> ShowS
[StateNum] -> ShowS
StateNum -> String
(Int -> StateNum -> ShowS)
-> (StateNum -> String) -> ([StateNum] -> ShowS) -> Show StateNum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StateNum] -> ShowS
$cshowList :: [StateNum] -> ShowS
show :: StateNum -> String
$cshow :: StateNum -> String
showsPrec :: Int -> StateNum -> ShowS
$cshowsPrec :: Int -> StateNum -> ShowS
Show)
    deriving Int -> StateNum -> Int
StateNum -> Int
(Int -> StateNum -> Int) -> (StateNum -> Int) -> Hashable StateNum
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: StateNum -> Int
$chash :: StateNum -> Int
hashWithSalt :: Int -> StateNum -> Int
$chashWithSalt :: Int -> StateNum -> Int
Hashable via Int
    deriving Coercible Int StateNum
Coercible Int StateNum -> Alignable StateNum
forall i. Coercible Int i -> Alignable i
Alignable.T via Alignable.Inst

data MState = MState
    {
        MState -> StateNum
stateNum      :: StateNum,
        MState -> T Trans
stateTrans    :: SymbolicIntMap.T Trans,
        MState -> [AltItem]
stateAltItems :: [AltItem]
    }
    deriving (MState -> MState -> Bool
(MState -> MState -> Bool)
-> (MState -> MState -> Bool) -> Eq MState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MState -> MState -> Bool
$c/= :: MState -> MState -> Bool
== :: MState -> MState -> Bool
$c== :: MState -> MState -> Bool
Eq, Int -> MState -> ShowS
[MState] -> ShowS
MState -> String
(Int -> MState -> ShowS)
-> (MState -> String) -> ([MState] -> ShowS) -> Show MState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MState] -> ShowS
$cshowList :: [MState] -> ShowS
show :: MState -> String
$cshow :: MState -> String
showsPrec :: Int -> MState -> ShowS
$cshowsPrec :: Int -> MState -> ShowS
Show)

data Trans
    = TransWithOps [TransOp] StateNum
    | TransReduce LAPEG.AltNum
    deriving (Trans -> Trans -> Bool
(Trans -> Trans -> Bool) -> (Trans -> Trans -> Bool) -> Eq Trans
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Trans -> Trans -> Bool
$c/= :: Trans -> Trans -> Bool
== :: Trans -> Trans -> Bool
$c== :: Trans -> Trans -> Bool
Eq, Int -> Trans -> ShowS
[Trans] -> ShowS
Trans -> String
(Int -> Trans -> ShowS)
-> (Trans -> String) -> ([Trans] -> ShowS) -> Show Trans
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Trans] -> ShowS
$cshowList :: [Trans] -> ShowS
show :: Trans -> String
$cshow :: Trans -> String
showsPrec :: Int -> Trans -> ShowS
$cshowsPrec :: Int -> Trans -> ShowS
Show)

data TransOp
    = TransOpEnter LAPEG.VarNum Bool (Maybe StateNum)
    | TransOpPushBackpoint StateNum
    | TransOpHandleNot LAPEG.AltNum
    | TransOpShift
    deriving (TransOp -> TransOp -> Bool
(TransOp -> TransOp -> Bool)
-> (TransOp -> TransOp -> Bool) -> Eq TransOp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TransOp -> TransOp -> Bool
$c/= :: TransOp -> TransOp -> Bool
== :: TransOp -> TransOp -> Bool
$c== :: TransOp -> TransOp -> Bool
Eq, Int -> TransOp -> ShowS
[TransOp] -> ShowS
TransOp -> String
(Int -> TransOp -> ShowS)
-> (TransOp -> String) -> ([TransOp] -> ShowS) -> Show TransOp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TransOp] -> ShowS
$cshowList :: [TransOp] -> ShowS
show :: TransOp -> String
$cshow :: TransOp -> String
showsPrec :: Int -> TransOp -> ShowS
$cshowsPrec :: Int -> TransOp -> ShowS
Show, (forall x. TransOp -> Rep TransOp x)
-> (forall x. Rep TransOp x -> TransOp) -> Generic TransOp
forall x. Rep TransOp x -> TransOp
forall x. TransOp -> Rep TransOp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TransOp x -> TransOp
$cfrom :: forall x. TransOp -> Rep TransOp x
Generic)

instance Hashable TransOp

data AltItem = AltItem
    { AltItem -> AltNum
altItemAltNum :: LAPEG.AltNum
    , AltItem -> Position
altItemCurPos :: LAPEG.Position
    }
    deriving (AltItem -> AltItem -> Bool
(AltItem -> AltItem -> Bool)
-> (AltItem -> AltItem -> Bool) -> Eq AltItem
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AltItem -> AltItem -> Bool
$c/= :: AltItem -> AltItem -> Bool
== :: AltItem -> AltItem -> Bool
$c== :: AltItem -> AltItem -> Bool
Eq, Int -> AltItem -> ShowS
[AltItem] -> ShowS
AltItem -> String
(Int -> AltItem -> ShowS)
-> (AltItem -> String) -> ([AltItem] -> ShowS) -> Show AltItem
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AltItem] -> ShowS
$cshowList :: [AltItem] -> ShowS
show :: AltItem -> String
$cshow :: AltItem -> String
showsPrec :: Int -> AltItem -> ShowS
$cshowsPrec :: Int -> AltItem -> ShowS
Show)