Commits

Mikhail Vorozhtsov  committed 9e211ce

Common implementations for 'wantInput', 'endOfInput', and 'atEnd'.

  • Participants
  • Parent commits 1d8b7ab

Comments (0)

Files changed (6)

File Data/Attoparsec/ByteString/Internal.hs

 -- Non-recursive so the bounds check can be inlined:
 {-# INLINE ensure #-}
 
--- | This parser always succeeds.  It returns 'True' if any input is
--- available either immediately or on demand, and 'False' if the end
--- of all input has been reached.
-wantInput :: Parser Bool
-wantInput = T.Parser $ \t pos more _lose succ ->
-  case () of
-    _ | lengthAtLeast pos 1 t -> succ t pos more True
-      | more == Complete -> succ t pos more False
-      | otherwise       -> let lose' t' pos' more' = succ t' pos' more' False
-                               succ' t' pos' more' = succ t' pos' more' True
-                           in prompt t pos more lose' succ'
-{-# INLINE wantInput #-}
-
--- | Match only if all input has been consumed.
-endOfInput :: Parser ()
-endOfInput = T.Parser $ \t pos more lose succ ->
-  case () of
-    _| lengthAtLeast pos 1 t -> lose t pos more [] "endOfInput"
-     | more == Complete -> succ t pos more ()
-     | otherwise ->
-       let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()
-           succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"
-       in  runParser demandInput t pos more lose' succ'
-
 -- | Return both the result of a parse and the portion of the input
 -- that was consumed while it was being parsed.
 match :: Parser a -> Parser (ByteString, a)
         succ t' pos' more' (substring pos (pos'-pos) t', a)
   in runParser p t pos more lose succ'
 
--- | Return an indication of whether the end of input has been
--- reached.
-atEnd :: Parser Bool
-atEnd = not <$> wantInput
-{-# INLINE atEnd #-}
-
 lengthAtLeast :: Pos -> Int -> Buffer -> Bool
 lengthAtLeast (Pos pos) n bs = Buf.length bs >= pos + n
 {-# INLINE lengthAtLeast #-}

File Data/Attoparsec/Combinator.hs

     , skipMany1
     , eitherP
     , feed
+    , endOfInput
+    , atEnd
     ) where
 
 import Control.Applicative (Alternative(..), Applicative(..), empty, liftA2,
                             many, (<|>), (*>), (<$>))
 import Control.Monad (MonadPlus(..))
 import Data.Attoparsec.Internal.Types (Parser(..), IResult(..))
+import Data.Attoparsec.Internal (endOfInput, atEnd)
 import Data.ByteString (ByteString)
 import Data.Monoid (Monoid(mappend))
 import Data.Text (Text)

File Data/Attoparsec/Internal.hs

-{-# LANGUAGE CPP, BangPatterns #-}
+{-# LANGUAGE CPP, BangPatterns, ScopedTypeVariables #-}
 -- |
 -- Module      :  Data.Attoparsec.Internal
 -- Copyright   :  Bryan O'Sullivan 2007-2014
     ( compareResults
     , prompt
     , demandInput
+    , wantInput
+    , endOfInput
+    , atEnd
     ) where
 
+import Control.Applicative ((<$>))
 #if __GLASGOW_HASKELL__ >= 700
 import Data.ByteString (ByteString)
 import Data.Text (Text)
 {-# SPECIALIZE demandInput :: Parser ByteString () #-}
 {-# SPECIALIZE demandInput :: Parser Text () #-}
 #endif
+
+-- | This parser always succeeds.  It returns 'True' if any input is
+-- available either immediately or on demand, and 'False' if the end
+-- of all input has been reached.
+wantInput :: forall t . Chunk t => Parser t Bool
+wantInput = Parser $ \t pos more _lose succ ->
+  case () of
+    _ | pos < atBufferEnd (undefined :: t) t -> succ t pos more True
+      | more == Complete -> succ t pos more False
+      | otherwise       -> let lose' t' pos' more' = succ t' pos' more' False
+                               succ' t' pos' more' = succ t' pos' more' True
+                           in prompt t pos more lose' succ'
+{-# INLINE wantInput #-}
+
+-- | Match only if all input has been consumed.
+endOfInput :: forall t . Chunk t => Parser t ()
+endOfInput = Parser $ \t pos more lose succ ->
+  case () of
+    _| pos < atBufferEnd (undefined :: t) t -> lose t pos more [] "endOfInput"
+     | more == Complete -> succ t pos more ()
+     | otherwise ->
+       let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()
+           succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"
+       in  runParser demandInput t pos more lose' succ'
+#if __GLASGOW_HASKELL__ >= 700
+{-# SPECIALIZE endOfInput :: Parser ByteString () #-}
+{-# SPECIALIZE endOfInput :: Parser Text () #-}
+#endif
+
+-- | Return an indication of whether the end of input has been
+-- reached.
+atEnd :: Chunk t => Parser t Bool
+atEnd = not <$> wantInput
+{-# INLINE atEnd #-}

File Data/Attoparsec/Internal/Types.hs

   nullChunk :: c -> Bool
   -- | Append chunk to a buffer.
   pappendChunk :: State c -> c -> State c
+  -- | Position at the end of a buffer. The first argument is ignored.
+  atBufferEnd :: c -> State c -> Pos
 
 instance Chunk ByteString where
   type ChunkElem ByteString = Word8
   {-# INLINE nullChunk #-}
   pappendChunk = B.pappend
   {-# INLINE pappendChunk #-}
+  atBufferEnd _ = Pos . B.length
+  {-# INLINE atBufferEnd #-}
 
 instance Chunk Text where
   type ChunkElem Text = Char
   {-# INLINE nullChunk #-}
   pappendChunk = T.pappend
   {-# INLINE pappendChunk #-}
+  atBufferEnd _ = Pos . T.length
+  {-# INLINE atBufferEnd #-}

File Data/Attoparsec/Text/Internal.hs

 -- Non-recursive so the bounds check can be inlined:
 {-# INLINE ensure #-}
 
--- | This parser always succeeds.  It returns 'True' if any input is
--- available either immediately or on demand, and 'False' if the end
--- of all input has been reached.
-wantInput :: Parser Bool
-wantInput = T.Parser $ \t pos more _lose succ ->
-  case () of
-    _ | pos < lengthOf t -> succ t pos more True
-      | more == Complete -> succ t pos more False
-      | otherwise       -> let lose' t' pos' more' = succ t' pos' more' False
-                               succ' t' pos' more' = succ t' pos' more' True
-                           in prompt t pos more lose' succ'
-
--- | Match only if all input has been consumed.
-endOfInput :: Parser ()
-endOfInput = T.Parser $ \t pos more lose succ ->
-  case () of
-    _| pos < lengthOf t -> lose t pos more [] "endOfInput"
-     | more == Complete -> succ t pos more ()
-     | otherwise ->
-       let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()
-           succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"
-       in  runParser demandInput t pos more lose' succ'
-
 -- | Return both the result of a parse and the portion of the input
 -- that was consumed while it was being parsed.
 match :: Parser a -> Parser (Text, a)
                               (substring pos (pos'-pos) t', a)
   in runParser p t pos more lose succ'
 
--- | Return an indication of whether the end of input has been
--- reached.
-atEnd :: Parser Bool
-atEnd = not <$> wantInput
-{-# INLINE atEnd #-}
-
 lengthAtLeast :: Pos -> Int -> Buffer -> Maybe Pos
 lengthAtLeast pos n t = go 0 (fromPos pos)
   where go i !p

File Data/Attoparsec/Types.hs

     (
       Parser
     , IResult(..)
+    , Chunk
     ) where
 
-import Data.Attoparsec.Internal.Types (Parser(..), IResult(..))
+import Data.Attoparsec.Internal.Types (Parser(..), IResult(..), Chunk)