packages feed

ptera-0.1.0.0: src/Language/Parser/Ptera/Scanner.hs

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 (Eq, Show)


newtype ListScanner e a = ListScanner
    {
        unListScanner :: State [e] a
    }
    deriving (Functor, Applicative, Monad) via State [e]

runListScanner :: ListScanner e a -> [e] -> a
runListScanner (ListScanner scanner) xs = evalState scanner xs

instance Scanner [e] e (ListScanner e) where
    consumeInput = ListScanner do
        get >>= \case
            [] ->
                pure Nothing
            x:xs -> do
                put xs
                pure do Just x

    getPosMark = ListScanner get

    seekToPosMark xs = ListScanner do put xs

    scanMode _ = pure ()