module Language.Parser.Ptera.Scanner where

import           Language.Parser.Ptera.Prelude


type T = Scanner

class Monad m => Scanner posMark elem m | m -> posMark, m -> elem where
    consumeInput :: m (Maybe elem)
    getPosMark :: m posMark
    seekToPosMark :: posMark -> m ()
    scanMode :: ScanMode posMark -> m ()

data ScanMode posMark
    = ScanModeNoBack
    | ScanModeNeedBack posMark
    deriving (ScanMode posMark -> ScanMode posMark -> Bool
(ScanMode posMark -> ScanMode posMark -> Bool)
-> (ScanMode posMark -> ScanMode posMark -> Bool)
-> Eq (ScanMode posMark)
forall posMark.
Eq posMark =>
ScanMode posMark -> ScanMode posMark -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ScanMode posMark -> ScanMode posMark -> Bool
$c/= :: forall posMark.
Eq posMark =>
ScanMode posMark -> ScanMode posMark -> Bool
== :: ScanMode posMark -> ScanMode posMark -> Bool
$c== :: forall posMark.
Eq posMark =>
ScanMode posMark -> ScanMode posMark -> Bool
Eq, Int -> ScanMode posMark -> ShowS
[ScanMode posMark] -> ShowS
ScanMode posMark -> String
(Int -> ScanMode posMark -> ShowS)
-> (ScanMode posMark -> String)
-> ([ScanMode posMark] -> ShowS)
-> Show (ScanMode posMark)
forall posMark. Show posMark => Int -> ScanMode posMark -> ShowS
forall posMark. Show posMark => [ScanMode posMark] -> ShowS
forall posMark. Show posMark => ScanMode posMark -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ScanMode posMark] -> ShowS
$cshowList :: forall posMark. Show posMark => [ScanMode posMark] -> ShowS
show :: ScanMode posMark -> String
$cshow :: forall posMark. Show posMark => ScanMode posMark -> String
showsPrec :: Int -> ScanMode posMark -> ShowS
$cshowsPrec :: forall posMark. Show posMark => Int -> ScanMode posMark -> ShowS
Show)


newtype ListScanner e a = ListScanner
    {
        ListScanner e a -> State [e] a
unListScanner :: State [e] a
    }
    deriving (a -> ListScanner e b -> ListScanner e a
(a -> b) -> ListScanner e a -> ListScanner e b
(forall a b. (a -> b) -> ListScanner e a -> ListScanner e b)
-> (forall a b. a -> ListScanner e b -> ListScanner e a)
-> Functor (ListScanner e)
forall a b. a -> ListScanner e b -> ListScanner e a
forall a b. (a -> b) -> ListScanner e a -> ListScanner e b
forall e a b. a -> ListScanner e b -> ListScanner e a
forall e a b. (a -> b) -> ListScanner e a -> ListScanner e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ListScanner e b -> ListScanner e a
$c<$ :: forall e a b. a -> ListScanner e b -> ListScanner e a
fmap :: (a -> b) -> ListScanner e a -> ListScanner e b
$cfmap :: forall e a b. (a -> b) -> ListScanner e a -> ListScanner e b
Functor, Functor (ListScanner e)
a -> ListScanner e a
Functor (ListScanner e)
-> (forall a. a -> ListScanner e a)
-> (forall a b.
    ListScanner e (a -> b) -> ListScanner e a -> ListScanner e b)
-> (forall a b c.
    (a -> b -> c)
    -> ListScanner e a -> ListScanner e b -> ListScanner e c)
-> (forall a b.
    ListScanner e a -> ListScanner e b -> ListScanner e b)
-> (forall a b.
    ListScanner e a -> ListScanner e b -> ListScanner e a)
-> Applicative (ListScanner e)
ListScanner e a -> ListScanner e b -> ListScanner e b
ListScanner e a -> ListScanner e b -> ListScanner e a
ListScanner e (a -> b) -> ListScanner e a -> ListScanner e b
(a -> b -> c)
-> ListScanner e a -> ListScanner e b -> ListScanner e c
forall e. Functor (ListScanner e)
forall a. a -> ListScanner e a
forall e a. a -> ListScanner e a
forall a b. ListScanner e a -> ListScanner e b -> ListScanner e a
forall a b. ListScanner e a -> ListScanner e b -> ListScanner e b
forall a b.
ListScanner e (a -> b) -> ListScanner e a -> ListScanner e b
forall e a b. ListScanner e a -> ListScanner e b -> ListScanner e a
forall e a b. ListScanner e a -> ListScanner e b -> ListScanner e b
forall e a b.
ListScanner e (a -> b) -> ListScanner e a -> ListScanner e b
forall a b c.
(a -> b -> c)
-> ListScanner e a -> ListScanner e b -> ListScanner e c
forall e a b c.
(a -> b -> c)
-> ListScanner e a -> ListScanner e b -> ListScanner e c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: ListScanner e a -> ListScanner e b -> ListScanner e a
$c<* :: forall e a b. ListScanner e a -> ListScanner e b -> ListScanner e a
*> :: ListScanner e a -> ListScanner e b -> ListScanner e b
$c*> :: forall e a b. ListScanner e a -> ListScanner e b -> ListScanner e b
liftA2 :: (a -> b -> c)
-> ListScanner e a -> ListScanner e b -> ListScanner e c
$cliftA2 :: forall e a b c.
(a -> b -> c)
-> ListScanner e a -> ListScanner e b -> ListScanner e c
<*> :: ListScanner e (a -> b) -> ListScanner e a -> ListScanner e b
$c<*> :: forall e a b.
ListScanner e (a -> b) -> ListScanner e a -> ListScanner e b
pure :: a -> ListScanner e a
$cpure :: forall e a. a -> ListScanner e a
$cp1Applicative :: forall e. Functor (ListScanner e)
Applicative, Applicative (ListScanner e)
a -> ListScanner e a
Applicative (ListScanner e)
-> (forall a b.
    ListScanner e a -> (a -> ListScanner e b) -> ListScanner e b)
-> (forall a b.
    ListScanner e a -> ListScanner e b -> ListScanner e b)
-> (forall a. a -> ListScanner e a)
-> Monad (ListScanner e)
ListScanner e a -> (a -> ListScanner e b) -> ListScanner e b
ListScanner e a -> ListScanner e b -> ListScanner e b
forall e. Applicative (ListScanner e)
forall a. a -> ListScanner e a
forall e a. a -> ListScanner e a
forall a b. ListScanner e a -> ListScanner e b -> ListScanner e b
forall a b.
ListScanner e a -> (a -> ListScanner e b) -> ListScanner e b
forall e a b. ListScanner e a -> ListScanner e b -> ListScanner e b
forall e a b.
ListScanner e a -> (a -> ListScanner e b) -> ListScanner e b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> ListScanner e a
$creturn :: forall e a. a -> ListScanner e a
>> :: ListScanner e a -> ListScanner e b -> ListScanner e b
$c>> :: forall e a b. ListScanner e a -> ListScanner e b -> ListScanner e b
>>= :: ListScanner e a -> (a -> ListScanner e b) -> ListScanner e b
$c>>= :: forall e a b.
ListScanner e a -> (a -> ListScanner e b) -> ListScanner e b
$cp1Monad :: forall e. Applicative (ListScanner e)
Monad) via State [e]

runListScanner :: ListScanner e a -> [e] -> a
runListScanner :: ListScanner e a -> [e] -> a
runListScanner (ListScanner State [e] a
scanner) [e]
xs = State [e] a -> [e] -> a
forall s a. State s a -> s -> a
evalState State [e] a
scanner [e]
xs

instance Scanner [e] e (ListScanner e) where
    consumeInput :: ListScanner e (Maybe e)
consumeInput = State [e] (Maybe e) -> ListScanner e (Maybe e)
forall e a. State [e] a -> ListScanner e a
ListScanner do
        StateT [e] Identity [e]
forall (m :: * -> *) s. Monad m => StateT s m s
get StateT [e] Identity [e]
-> ([e] -> State [e] (Maybe e)) -> State [e] (Maybe e)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            [] ->
                Maybe e -> State [e] (Maybe e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe e
forall a. Maybe a
Nothing
            e
x:[e]
xs -> do
                [e] -> StateT [e] Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put [e]
xs
                Maybe e -> State [e] (Maybe e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure do e -> Maybe e
forall a. a -> Maybe a
Just e
x

    getPosMark :: ListScanner e [e]
getPosMark = StateT [e] Identity [e] -> ListScanner e [e]
forall e a. State [e] a -> ListScanner e a
ListScanner StateT [e] Identity [e]
forall (m :: * -> *) s. Monad m => StateT s m s
get

    seekToPosMark :: [e] -> ListScanner e ()
seekToPosMark [e]
xs = StateT [e] Identity () -> ListScanner e ()
forall e a. State [e] a -> ListScanner e a
ListScanner do [e] -> StateT [e] Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put [e]
xs

    scanMode :: ScanMode [e] -> ListScanner e ()
scanMode ScanMode [e]
_ = () -> ListScanner e ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()