    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE BangPatterns #-}

    module Yi.IncrementalParse (recoverWith, symbol, eof, lookNext, testNext,
                                State, P, Parser(..), AlexState (..), scanner) where

    import           Parser.Incremental (Parser (..), Process, eof, evalL, evalR,
                                         lookNext, mkProcess, pushEof, pushSyms,
                                         recoverWith, symbol, testNext)

    import           Yi.Lexer.Alex      (AlexState (..))
    import           Yi.Syntax          (Scanner (..))

    type P s a = Parser s a

    type State st token result = (st, Process token result)

    scanner :: forall st token result. Parser token result -> Scanner st token -> Scanner (State st token result) result
    scanner :: forall st token result.
    Parser token result
    -> Scanner st token -> Scanner (State st token result) result
    scanner Parser token result
    parser Scanner st token
    input = Scanner
        {
          scanInit :: (st, Process token result)
    scanInit = (Scanner st token -> st
    forall st a. Scanner st a -> st
    scanInit Scanner st token
    input, Parser token result -> Process token result
    forall s a. Parser s a -> Process s a
    mkProcess Parser token result
    parser),
          scanLooked :: (st, Process token result) -> Point
    scanLooked = Scanner st token -> st -> Point
    forall st a. Scanner st a -> st -> Point
    scanLooked Scanner st token
    input (st -> Point)
    -> ((st, Process token result) -> st)
    -> (st, Process token result)
    -> Point
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (st, Process token result) -> st
    forall a b. (a, b) -> a
    fst,
          scanRun :: (st, Process token result)
    -> [((st, Process token result), result)]
    scanRun = (st, Process token result)
    -> [((st, Process token result), result)]
    run,
          scanEmpty :: result
    scanEmpty = (result, [String]) -> result
    forall a b. (a, b) -> a
    fst ((result, [String]) -> result) -> (result, [String]) -> result
    forall a b. (a -> b) -> a -> b
    $ Process token result -> (result, [String])
    forall token a rest. Zip token (a :< rest) -> (a, [String])
    evalR (Process token result -> (result, [String]))
    -> Process token result -> (result, [String])
    forall a b. (a -> b) -> a -> b
    $ Process token result -> Process token result
    forall s r. Zip s r -> Zip s r
    pushEof (Process token result -> Process token result)
    -> Process token result -> Process token result
    forall a b. (a -> b) -> a -> b
    $ Parser token result -> Process token result
    forall s a. Parser s a -> Process s a
    mkProcess Parser token result
    parser
        }
        where
            run :: State st token result -> [(State st token result, result)]
            run :: (st, Process token result)
    -> [((st, Process token result), result)]
    run (st
    st,Process token result
    process) = Process token result
    -> [(st, token)] -> [((st, Process token result), result)]
    updateState0 Process token result
    process ([(st, token)] -> [((st, Process token result), result)])
    -> [(st, token)] -> [((st, Process token result), result)]
    forall a b. (a -> b) -> a -> b
    $ Scanner st token -> st -> [(st, token)]
    forall st a. Scanner st a -> st -> [(st, a)]
    scanRun Scanner st token
    input st
    st

            updateState0 :: Process token result -> [(st,token)] -> [(State st token result, result)]
            updateState0 :: Process token result
    -> [(st, token)] -> [((st, Process token result), result)]
    updateState0 Process token result
    _        [] = []
            updateState0 Process token result
    curState toks :: [(st, token)]
    toks@((st
    st,token
    tok):[(st, token)]
    rest) = ((st
    st, Process token result
    curState), result
    result) ((st, Process token result), result)
    -> [((st, Process token result), result)]
    -> [((st, Process token result), result)]
    forall a. a -> [a] -> [a]
    : Process token result
    -> [(st, token)] -> [((st, Process token result), result)]
    updateState0 Process token result
    nextState [(st, token)]
    rest
                where !nextState :: Process token result
    nextState =       Process token result -> Process token result
    forall s r. Zip s r -> Zip s r
    evalL (Process token result -> Process token result)
    -> Process token result -> Process token result
    forall a b. (a -> b) -> a -> b
    $           [token] -> Process token result -> Process token result
    forall s r. [s] -> Zip s r -> Zip s r
    pushSyms [token
    tok]           Process token result
    curState
                      result :: result
    result    = (result, [String]) -> result
    forall a b. (a, b) -> a
    fst ((result, [String]) -> result) -> (result, [String]) -> result
    forall a b. (a -> b) -> a -> b
    $ Process token result -> (result, [String])
    forall token a rest. Zip token (a :< rest) -> (a, [String])
    evalR (Process token result -> (result, [String]))
    -> Process token result -> (result, [String])
    forall a b. (a -> b) -> a -> b
    $ Process token result -> Process token result
    forall s r. Zip s r -> Zip s r
    pushEof (Process token result -> Process token result)
    -> Process token result -> Process token result
    forall a b. (a -> b) -> a -> b
    $ [token] -> Process token result -> Process token result
    forall s r. [s] -> Zip s r -> Zip s r
    pushSyms (((st, token) -> token) -> [(st, token)] -> [token]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (st, token) -> token
    forall a b. (a, b) -> b
    snd [(st, token)]
    toks) Process token result
    curState