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
    { forall start varDoc altDoc a.
SRB start varDoc altDoc a -> EnumMap start StateNum
initials :: EnumMap.EnumMap start StateNum
    , forall start varDoc altDoc a.
SRB start varDoc altDoc a -> T StateNum MState
states   :: AlignableArray.T StateNum MState
    , forall start varDoc altDoc a.
SRB start varDoc altDoc a -> T AltNum (Alt altDoc a)
alts     :: AlignableArray.T LAPEG.AltNum (LAPEG.Alt altDoc a)
    , forall start varDoc 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
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
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, 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
<$ :: forall a b.
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 :: forall a b.
(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
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
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 Eq StateNum
Int -> StateNum -> Int
StateNum -> Int
forall a. Eq 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
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
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
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
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
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
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
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. 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
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
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)