module Text.LParse.Atomics where
import Control.DoubleContinuations
import Control.Applicative
import Control.Monad
import Data.Char
import Text.LParse.Parser
import Text.LParse.Transformers
import Text.LParse.TokenStream
noop :: Parser r t ()
noop = return ()
full :: Parser r [t] [t]
full = many tokenReturn
discard :: Parser r [t] ()
discard = void full
eoi :: Parser r [t] ()
eoi = cParse null noop ("Input not fully consumed")
tokenParse :: (TokenStream s) => (t -> a) -> Parser r (s t) a
tokenParse f = Parser (\s -> DCont (\btr etr -> if null s then etr "Unexpected EOI" else btr (f $ top s,rest s)))
tokenReturn :: (TokenStream s) => Parser r (s a) a
tokenReturn = tokenParse id
consume :: (Eq t, Show (s t), TokenStream s) => (s t) -> Parser r (s t) ()
consume pre = cParse ((&&) <$> (all id . sZipWith (==) pre) <*> ((>= length pre) . length)) (pParse (sDrop (length pre)) noop) ("Expected " ++ show pre)
consumeSingle :: (Eq t, Show t, TokenStream s) => t -> Parser r (s t) ()
consumeSingle t = cParse (\s -> not (null s) && top s == t) (pParse rest noop) ("Expected " ++ show t)
digit :: Parser r String Integer
digit = read . return <$> cParse (\s -> not (null s) && isDigit (head s)) tokenReturn "Expected digit"
letter :: Parser r String Char
letter = cParse (\s -> not (null s) && isLetter (head s)) tokenReturn "Expected letter"
word :: Parser r String String
word = some letter
integer :: Parser r String Integer
integer = foldl (\x y -> x*10+y) 0 <$> some digit
peek :: (TokenStream s) => (t -> Bool) -> String -> Parser r (s t) ()
peek c = cParse (c . top) noop