module Language.Parser.Ptera.Runner (
    T,

    RunnerM (..),
    Result,
    RunT.ParseResult (..),
    runParserM,
    runParser,
) where

import           Language.Parser.Ptera.Prelude

import qualified Language.Parser.Ptera.Runner.Parser      as Parser
import qualified Language.Parser.Ptera.Runner.RunT        as RunT
import qualified Language.Parser.Ptera.Scanner            as Scanner
import qualified Language.Parser.Ptera.Syntax             as Syntax
import qualified Language.Parser.Ptera.Syntax.SafeGrammar as SafeGrammar
import qualified Type.Membership                          as Membership
import qualified Type.Membership.Internal                 as MembershipInternal

type T = RunnerM

type RunnerM :: Type -> Type -> Type -> [Symbol] -> Type
newtype RunnerM ctx rules elem initials = UnsafeRunnerM
    { forall ctx rules elem (initials :: [Symbol]).
RunnerM ctx rules elem initials -> T ctx elem ()
unRunnerM :: Parser.T ctx elem ()
    }

type Runner = RunnerM ()

type Result posMark = RunT.ParseResult posMark ()

runParserM :: forall v initials ctx posMark m rules elem proxy
    .  Membership.Member initials v => Scanner.T posMark elem m
    => proxy v -> RunnerM ctx rules elem initials -> ctx
    -> m (Result posMark (Syntax.RuleExprReturnType rules v))
runParserM :: forall (v :: Symbol) (initials :: [Symbol]) ctx posMark
       (m :: * -> *) rules elem (proxy :: Symbol -> *).
(Member initials v, T posMark elem m) =>
proxy v
-> RunnerM ctx rules elem initials
-> ctx
-> m (Result posMark (RuleExprReturnType rules v))
runParserM proxy v
_ (UnsafeRunnerM T ctx elem ()
p) ctx
customCtx0 =
    case forall ctx elem altHelp posMark.
T ctx elem altHelp
-> ctx -> StartNum -> Maybe (Context ctx posMark elem altHelp)
RunT.initialContext T ctx elem ()
p ctx
customCtx0 StartNum
pos of
        Maybe (Context ctx posMark elem ())
Nothing ->
            forall a. HasCallStack => [Char] -> a
error [Char]
"Not found the start point."
        Just Context ctx posMark elem ()
initialCtx ->
            forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT
                do forall ctx posMark elem altHelp (m :: * -> *) a.
RunT ctx posMark elem altHelp m a
-> StateT (Context ctx posMark elem altHelp) m a
RunT.unRunT forall ctx posMark elem altHelp (m :: * -> *) a.
T posMark elem m =>
RunT ctx posMark elem altHelp m (ParseResult posMark altHelp a)
RunT.runT
                Context ctx posMark elem ()
initialCtx
    where
        pos :: StartNum
pos = forall {k} (initials :: [k]) (v :: k).
Membership initials v -> StartNum
SafeGrammar.genStartPoint
            do forall {k} (xs :: [k]) (x :: k). Member xs x => Membership xs x
MembershipInternal.membership @initials @v

runParser :: forall v initials posMark m rules elem proxy
    .  Membership.Member initials v => Scanner.T posMark elem m
    => proxy v -> Runner rules elem initials
    -> m (Result posMark (Syntax.RuleExprReturnType rules v))
runParser :: forall (v :: Symbol) (initials :: [Symbol]) posMark (m :: * -> *)
       rules elem (proxy :: Symbol -> *).
(Member initials v, T posMark elem m) =>
proxy v
-> Runner rules elem initials
-> m (Result posMark (RuleExprReturnType rules v))
runParser proxy v
p Runner rules elem initials
r = forall (v :: Symbol) (initials :: [Symbol]) ctx posMark
       (m :: * -> *) rules elem (proxy :: Symbol -> *).
(Member initials v, T posMark elem m) =>
proxy v
-> RunnerM ctx rules elem initials
-> ctx
-> m (Result posMark (RuleExprReturnType rules v))
runParserM proxy v
p Runner rules elem initials
r ()