module Language.Parser.Ptera.Pipeline.SafeGrammar2SRB where

import           Language.Parser.Ptera.Prelude

import qualified Language.Parser.Ptera.Data.Alignable.Array as AlignableArray
import qualified Language.Parser.Ptera.Data.Alignable.Set   as AlignableSet
import qualified Language.Parser.Ptera.Machine.PEG          as PEG
import qualified Language.Parser.Ptera.Machine.SRB          as SRB
import qualified Language.Parser.Ptera.Pipeline.Grammar2PEG as Grammar2PEG
import qualified Language.Parser.Ptera.Pipeline.LAPEG2SRB   as LAPEG2SRB
import qualified Language.Parser.Ptera.Pipeline.PEG2LAPEG   as PEG2LAPEG
import qualified Language.Parser.Ptera.Syntax.Grammar       as Grammar
import qualified Language.Parser.Ptera.Syntax.SafeGrammar   as SafeGrammar

safeGrammar2Srb :: SafeGrammar.T action rules tokens elem initials
    -> Either [StringLit] (SRB.T Int StringLit (Maybe ()) (Grammar.Action action))
safeGrammar2Srb :: T action rules tokens elem initials
-> Either [StringLit] (T Int StringLit (Maybe ()) (Action action))
safeGrammar2Srb (SafeGrammar.UnsafeGrammar FixedGrammar Int Int Int elem StringLit (Maybe ()) action
g) = do
    let peg :: T Int StringLit (Maybe ()) (Action action)
peg = FixedGrammar Int Int Int elem StringLit (Maybe ()) action
-> T Int StringLit (Maybe ()) (Action action)
forall start nonTerminal terminal elem varDoc altDoc
       (action :: [*] -> * -> *).
(Enum start, Enum nonTerminal, Enum terminal) =>
FixedGrammar start nonTerminal terminal elem varDoc altDoc action
-> T start varDoc altDoc (Action action)
Grammar2PEG.grammar2Peg FixedGrammar Int Int Int elem StringLit (Maybe ()) action
g
    T Int StringLit (Maybe ()) (Action action)
laPeg <- case Except (T VarNum) (T Int StringLit (Maybe ()) (Action action))
-> Either (T VarNum) (T Int StringLit (Maybe ()) (Action action))
forall e a. Except e a -> Either e a
runExcept do T Int StringLit (Maybe ()) (Action action)
-> Except (T VarNum) (T Int StringLit (Maybe ()) (Action action))
forall start varDoc altDoc a.
Enum start =>
T start varDoc altDoc a
-> Except (T VarNum) (T start varDoc altDoc a)
PEG2LAPEG.peg2LaPeg T Int StringLit (Maybe ()) (Action action)
peg of
        Right T Int StringLit (Maybe ()) (Action action)
x -> T Int StringLit (Maybe ()) (Action action)
-> Either [StringLit] (T Int StringLit (Maybe ()) (Action action))
forall a b. b -> Either a b
Right T Int StringLit (Maybe ()) (Action action)
x
        Left T VarNum
vns -> do
            let vs :: T VarNum (Var StringLit)
vs = T Int StringLit (Maybe ()) (Action action)
-> T VarNum (Var StringLit)
forall start varDoc altDoc a.
PEG start varDoc altDoc a -> T VarNum (Var varDoc)
PEG.vars T Int StringLit (Maybe ()) (Action action)
peg
            [StringLit]
-> Either [StringLit] (T Int StringLit (Maybe ()) (Action action))
forall a b. a -> Either a b
Left
                [ Var StringLit -> StringLit
forall varDoc. Var varDoc -> varDoc
PEG.varHelp do T VarNum (Var StringLit) -> VarNum -> Var StringLit
forall n a. T n => Array n a -> n -> a
AlignableArray.forceIndex T VarNum (Var StringLit)
vs VarNum
vn
                | VarNum
vn <- T VarNum -> [VarNum]
forall n. T n => Set n -> [n]
AlignableSet.toList T VarNum
vns
                ]
    T Int StringLit (Maybe ()) (Action action)
-> Either [StringLit] (T Int StringLit (Maybe ()) (Action action))
forall (f :: * -> *) a. Applicative f => a -> f a
pure do T Int StringLit (Maybe ()) (Action action)
-> T Int StringLit (Maybe ()) (Action action)
forall start varDoc altDoc a.
Enum start =>
T start varDoc altDoc a -> T start varDoc altDoc a
LAPEG2SRB.laPeg2Srb T Int StringLit (Maybe ()) (Action action)
laPeg