module Parsimony.Stream (Token(..), Stream(..)) where
import Parsimony.Prim
import Parsimony.Pos
import Parsimony.Error
import qualified Data.ByteString as Strict (ByteString,uncons)
import qualified Data.ByteString.Lazy as Lazy (ByteString,uncons)
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import Data.Word (Word8)
import Numeric (showHex)
class Token token where
updatePos :: token -> SourcePos -> SourcePos
showToken :: token -> String
instance Token Char where
updatePos c p = updatePosChar p c
showToken = show
instance Token Word8 where
updatePos _ p = incSourceColumn p 1
showToken b = "0x" ++ showHex b ""
class Token token => Stream stream token | stream -> token where
getToken :: PrimParser stream token
eof_err :: SourcePos -> Reply s a
eof_err p = Error $ newErrorMessage (UnExpect "end of input") p
genToken :: Token t => (i -> Maybe (t,i)) -> PrimParser i t
genToken unc (State i p) =
case unc i of
Nothing -> eof_err p
Just (t,ts) -> Ok t State { stateInput = ts
, statePos = updatePos t p
}
instance Token a => Stream [a] a where
getToken = genToken (\xs -> case xs of
[] -> Nothing
c : cs -> Just (c,cs))
instance Stream Strict.ByteString Word8 where
getToken = genToken Strict.uncons
instance Stream Lazy.ByteString Word8 where
getToken = genToken Lazy.uncons
instance Stream T.Text Char where
getToken = genToken T.uncons
instance Stream LT.Text Char where
getToken = genToken LT.uncons