{-# 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 :: Parser token result
-> Scanner st token -> Scanner (State st token result) result
scanner Parser token result
parser Scanner st token
input = Scanner :: forall st a.
st -> (st -> Point) -> a -> (st -> [(st, a)]) -> Scanner st a
Scanner
    {
      scanInit :: State st 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 :: State st token result -> Point
scanLooked = Scanner st token -> st -> Point
forall st a. Scanner st a -> st -> Point
scanLooked Scanner st token
input (st -> Point)
-> (State st token result -> st) -> State st token result -> Point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. State st token result -> st
forall a b. (a, b) -> a
fst,
      scanRun :: State st token result -> [(State st token result, result)]
scanRun = State st token result -> [(State st 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 :: State st token result -> [(State st token result, result)]
run (st
st,Process token result
process) = Process token result
-> [(st, token)] -> [(State st token result, result)]
updateState0 Process token result
process ([(st, token)] -> [(State st token result, result)])
-> [(st, token)] -> [(State st 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)] -> [(State st 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) (State st token result, result)
-> [(State st token result, result)]
-> [(State st token result, result)]
forall a. a -> [a] -> [a]
: Process token result
-> [(st, token)] -> [(State st 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 (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