module Language.Parser.Ptera.Machine.LAPEG 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.IntSet as SymbolicIntSet
import qualified Language.Parser.Ptera.Machine.PEG          as PEG


type T = LAPEG

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

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

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

data Rule = Rule
    { Rule -> HeadRange
ruleRange :: HeadRange
    , Rule -> [AltNum]
ruleAlts  :: [AltNum]
    }
    deriving (Rule -> Rule -> Bool
(Rule -> Rule -> Bool) -> (Rule -> Rule -> Bool) -> Eq Rule
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rule -> Rule -> Bool
$c/= :: Rule -> Rule -> Bool
== :: Rule -> Rule -> Bool
$c== :: Rule -> Rule -> Bool
Eq, Int -> Rule -> ShowS
[Rule] -> ShowS
Rule -> String
(Int -> Rule -> ShowS)
-> (Rule -> String) -> ([Rule] -> ShowS) -> Show Rule
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Rule] -> ShowS
$cshowList :: [Rule] -> ShowS
show :: Rule -> String
$cshow :: Rule -> String
showsPrec :: Int -> Rule -> ShowS
$cshowsPrec :: Int -> Rule -> ShowS
Show)

data Alt altDoc a = Alt
    { Alt altDoc a -> VarNum
altVar                  :: VarNum
    , Alt altDoc a -> AltKind
altKind                 :: PEG.AltKind
    , Alt altDoc a -> T Position (HeadRange, Unit)
altUnitSeqWithLookAHead :: AlignableArray.T Position (HeadRange, Unit)
    , Alt altDoc a -> a
altAction               :: a
    , Alt altDoc a -> altDoc
altHelp                 :: altDoc
    }
    deriving (Alt altDoc a -> Alt altDoc a -> Bool
(Alt altDoc a -> Alt altDoc a -> Bool)
-> (Alt altDoc a -> Alt altDoc a -> Bool) -> Eq (Alt altDoc a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall altDoc a.
(Eq a, Eq altDoc) =>
Alt altDoc a -> Alt altDoc a -> Bool
/= :: Alt altDoc a -> Alt altDoc a -> Bool
$c/= :: forall altDoc a.
(Eq a, Eq altDoc) =>
Alt altDoc a -> Alt altDoc a -> Bool
== :: Alt altDoc a -> Alt altDoc a -> Bool
$c== :: forall altDoc a.
(Eq a, Eq altDoc) =>
Alt altDoc a -> Alt altDoc a -> Bool
Eq, Int -> Alt altDoc a -> ShowS
[Alt altDoc a] -> ShowS
Alt altDoc a -> String
(Int -> Alt altDoc a -> ShowS)
-> (Alt altDoc a -> String)
-> ([Alt altDoc a] -> ShowS)
-> Show (Alt altDoc a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall altDoc a.
(Show a, Show altDoc) =>
Int -> Alt altDoc a -> ShowS
forall altDoc a. (Show a, Show altDoc) => [Alt altDoc a] -> ShowS
forall altDoc a. (Show a, Show altDoc) => Alt altDoc a -> String
showList :: [Alt altDoc a] -> ShowS
$cshowList :: forall altDoc a. (Show a, Show altDoc) => [Alt altDoc a] -> ShowS
show :: Alt altDoc a -> String
$cshow :: forall altDoc a. (Show a, Show altDoc) => Alt altDoc a -> String
showsPrec :: Int -> Alt altDoc a -> ShowS
$cshowsPrec :: forall altDoc a.
(Show a, Show altDoc) =>
Int -> Alt altDoc a -> ShowS
Show, a -> Alt altDoc b -> Alt altDoc a
(a -> b) -> Alt altDoc a -> Alt altDoc b
(forall a b. (a -> b) -> Alt altDoc a -> Alt altDoc b)
-> (forall a b. a -> Alt altDoc b -> Alt altDoc a)
-> Functor (Alt altDoc)
forall a b. a -> Alt altDoc b -> Alt altDoc a
forall a b. (a -> b) -> Alt altDoc a -> Alt altDoc b
forall altDoc a b. a -> Alt altDoc b -> Alt altDoc a
forall altDoc a b. (a -> b) -> Alt altDoc a -> Alt altDoc b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Alt altDoc b -> Alt altDoc a
$c<$ :: forall altDoc a b. a -> Alt altDoc b -> Alt altDoc a
fmap :: (a -> b) -> Alt altDoc a -> Alt altDoc b
$cfmap :: forall altDoc a b. (a -> b) -> Alt altDoc a -> Alt altDoc b
Functor)

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

data HeadRange = HeadRange
    { HeadRange -> Bool
headRangeEpsilon :: Bool
    , HeadRange -> T
headRangeConsume :: SymbolicIntSet.T
    }
    deriving (HeadRange -> HeadRange -> Bool
(HeadRange -> HeadRange -> Bool)
-> (HeadRange -> HeadRange -> Bool) -> Eq HeadRange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HeadRange -> HeadRange -> Bool
$c/= :: HeadRange -> HeadRange -> Bool
== :: HeadRange -> HeadRange -> Bool
$c== :: HeadRange -> HeadRange -> Bool
Eq, Int -> HeadRange -> ShowS
[HeadRange] -> ShowS
HeadRange -> String
(Int -> HeadRange -> ShowS)
-> (HeadRange -> String)
-> ([HeadRange] -> ShowS)
-> Show HeadRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HeadRange] -> ShowS
$cshowList :: [HeadRange] -> ShowS
show :: HeadRange -> String
$cshow :: HeadRange -> String
showsPrec :: Int -> HeadRange -> ShowS
$cshowsPrec :: Int -> HeadRange -> ShowS
Show)

instance Semigroup HeadRange where
    HeadRange
hr1 <> :: HeadRange -> HeadRange -> HeadRange
<> HeadRange
hr2 = HeadRange :: Bool -> T -> HeadRange
HeadRange
        { $sel:headRangeEpsilon:HeadRange :: Bool
headRangeEpsilon = HeadRange -> Bool
headRangeEpsilon HeadRange
hr1 Bool -> Bool -> Bool
|| HeadRange -> Bool
headRangeEpsilon HeadRange
hr2
        , $sel:headRangeConsume:HeadRange :: T
headRangeConsume = HeadRange -> T
headRangeConsume HeadRange
hr1 T -> T -> T
forall a. Semigroup a => a -> a -> a
<> HeadRange -> T
headRangeConsume HeadRange
hr2
        }

instance Monoid HeadRange where
    mempty :: HeadRange
mempty = HeadRange :: Bool -> T -> HeadRange
HeadRange
        { $sel:headRangeEpsilon:HeadRange :: Bool
headRangeEpsilon = Bool
False
        , $sel:headRangeConsume:HeadRange :: T
headRangeConsume = T
forall a. Monoid a => a
mempty
        }

data Unit
    = UnitTerminal Terminal
    | UnitNonTerminal VarNum
    | UnitNot
    deriving (Unit -> Unit -> Bool
(Unit -> Unit -> Bool) -> (Unit -> Unit -> Bool) -> Eq Unit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Unit -> Unit -> Bool
$c/= :: Unit -> Unit -> Bool
== :: Unit -> Unit -> Bool
$c== :: Unit -> Unit -> Bool
Eq, Int -> Unit -> ShowS
[Unit] -> ShowS
Unit -> String
(Int -> Unit -> ShowS)
-> (Unit -> String) -> ([Unit] -> ShowS) -> Show Unit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Unit] -> ShowS
$cshowList :: [Unit] -> ShowS
show :: Unit -> String
$cshow :: Unit -> String
showsPrec :: Int -> Unit -> ShowS
$cshowsPrec :: Int -> Unit -> ShowS
Show)

type Terminal = Int