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
    { forall start varDoc altDoc a.
LAPEG start varDoc altDoc a -> T VarNum (Var varDoc)
vars     :: AlignableArray.T VarNum (PEG.Var varDoc)
    , forall start varDoc altDoc a.
LAPEG start varDoc altDoc a -> T VarNum Rule
rules    :: AlignableArray.T VarNum Rule
    , forall start varDoc altDoc a.
LAPEG start varDoc altDoc a -> T AltNum (Alt altDoc a)
alts     :: AlignableArray.T AltNum (Alt altDoc a)
    , forall start varDoc 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
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
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, 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
<$ :: forall a b.
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 :: forall a b.
(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
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
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 Eq VarNum
Int -> VarNum -> Int
VarNum -> Int
forall a. Eq 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
forall i. Coercible Int i -> Alignable i
Alignable.T via Alignable.Inst

newtype AltNum = AltNum Int
    deriving (AltNum -> AltNum -> Bool
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
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 Eq AltNum
Int -> AltNum -> Int
AltNum -> Int
forall a. Eq 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
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
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
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
    { forall altDoc a. Alt altDoc a -> VarNum
altVar                  :: VarNum
    , forall altDoc a. Alt altDoc a -> AltKind
altKind                 :: PEG.AltKind
    , forall altDoc a. Alt altDoc a -> T Position (HeadRange, Unit)
altUnitSeqWithLookAHead :: AlignableArray.T Position (HeadRange, Unit)
    , forall altDoc a. Alt altDoc a -> a
altAction               :: a
    , forall altDoc a. Alt altDoc a -> altDoc
altHelp                 :: altDoc
    }
    deriving (Alt altDoc a -> Alt altDoc a -> Bool
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
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, 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
<$ :: forall a b. a -> Alt altDoc b -> Alt altDoc a
$c<$ :: forall altDoc a b. a -> Alt altDoc b -> Alt altDoc a
fmap :: forall a b. (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
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
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 Eq Position
Int -> Position -> Int
Position -> Int
forall a. Eq 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
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
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
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
        { $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 forall a. Semigroup a => a -> a -> a
<> HeadRange -> T
headRangeConsume HeadRange
hr2
        }

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

data Unit
    = UnitTerminal Terminal
    | UnitNonTerminal VarNum
    | UnitNot
    deriving (Unit -> Unit -> Bool
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
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