@@ -95,10 +95,10 @@ instance (a ~ Text) => IsString (Parser a) where
95-- > where isDigit c = c >= '0' && c <= '9'
95-- > where isDigit c = c >= '0' && c <= '9'
96satisfy :: (Char -> Bool) -> Parser Char
96satisfy :: (Char -> Bool) -> Parser Char
97satisfy p = do
97satisfy p = do
98− c <- ensure 1
98+ (k,c) <- ensure 1
99 let !h = T.unsafeHead c
99 let !h = T.unsafeHead c
101− then advance 1 >> return h
101+ then advance k >> return h
102 else fail "satisfy"
102 else fail "satisfy"
103{-# INLINE satisfy #-}
103{-# INLINE satisfy #-}
@@ -109,9 +109,9 @@ satisfy p = do
109-- > where isDigit c = c >= '0' && c <= '9'
109-- > where isDigit c = c >= '0' && c <= '9'
110skip :: (Char -> Bool) -> Parser ()
110skip :: (Char -> Bool) -> Parser ()
111skip p = do
111skip p = do
112− s <- ensure 1
112+ (k,s) <- ensure 1
113 if p (T.head s)
113 if p (T.head s)
114− then advance 1
114+ then advance k
115 else fail "skip"
115 else fail "skip"
117-- | The parser @satisfyWith f p@ transforms a character, and succeeds
117-- | The parser @satisfyWith f p@ transforms a character, and succeeds
@@ -119,10 +119,10 @@ skip p = do
119-- parser returns the transformed character that was parsed.
119-- parser returns the transformed character that was parsed.
120satisfyWith :: (Char -> a) -> (a -> Bool) -> Parser a
120satisfyWith :: (Char -> a) -> (a -> Bool) -> Parser a
121satisfyWith f p = do
121satisfyWith f p = do
122− s <- ensure 1
122+ (k,s) <- ensure 1
123 let c = f $! T.head s
123 let c = f $! T.head s
125− then advance 1 >> return c
125+ then advance k >> return c
126 else fail "satisfyWith"
126 else fail "satisfyWith"
127{-# INLINE satisfyWith #-}
127{-# INLINE satisfyWith #-}
@@ -130,10 +130,10 @@ satisfyWith f p = do
130-- predicate returns 'True'.
130-- predicate returns 'True'.
131takeWith :: Int -> (Text -> Bool) -> Parser Text
131takeWith :: Int -> (Text -> Bool) -> Parser Text
132takeWith n p = do
132takeWith n p = do
133− s <- ensure n
133+ (k,s) <- ensure n
134 let h = T.take n s
134 let h = T.take n s
136− then advance n >> return h
136+ then advance k >> return h
137 else fail "takeWith"
137 else fail "takeWith"
139-- | Consume exactly @n@ characters of input.
139-- | Consume exactly @n@ characters of input.
@@ -172,9 +172,9 @@ stringCI s = go 0
173 | n > T.length fs = fail "stringCI"
173 | n > T.length fs = fail "stringCI"
174 | otherwise = do
174 | otherwise = do
175− t <- ensure n
175+ (k,t) <- ensure n
176 if T.toCaseFold t == fs
176 if T.toCaseFold t == fs
177− then advance n >> return t
177+ then advance k >> return t
178 else go (n+1)
178 else go (n+1)
179 fs = T.toCaseFold s
179 fs = T.toCaseFold s
180{-# INLINE stringCI #-}
180{-# INLINE stringCI #-}
@@ -183,10 +183,10 @@ stringCI s = go 0
183-- | Satisfy a literal string, ignoring case for characters in the ASCII range.
183-- | Satisfy a literal string, ignoring case for characters in the ASCII range.
184asciiCI :: Text -> Parser Text
184asciiCI :: Text -> Parser Text
185asciiCI input = do
185asciiCI input = do
186− t <- ensure n
186+ (k,t) <- ensure n
187 let h = T.take n t
187 let h = T.take n t
188 if asciiToLower h == s
188 if asciiToLower h == s
189− then advance n >> return h
189+ then advance k >> return h
190 else fail "asciiCI"
190 else fail "asciiCI"
192 n = T.length input
192 n = T.length input
@@ -397,7 +397,7 @@ peekChar = T.Parser $ \t pos more _lose succ ->
397-- input, but will fail if end of input has been reached.
397-- input, but will fail if end of input has been reached.
398peekChar' :: Parser Char
398peekChar' :: Parser Char
399peekChar' = do
399peekChar' = do
400− s <- ensure 1
400+ (_,s) <- ensure 1
401 return $! T.head s
401 return $! T.head s
402{-# INLINE peekChar' #-}
402{-# INLINE peekChar' #-}
@@ -445,21 +445,21 @@ advance n = T.Parser $ \t pos more _lose succ ->
445{-# INLINE advance #-}
445{-# INLINE advance #-}
447ensureSuspended :: Int -> Text -> Pos -> More
447ensureSuspended :: Int -> Text -> Pos -> More
448− -> Failure r -> Success Text r
448+ -> Failure r -> Success (Int,Text) r
449 -> Result r
449 -> Result r
450ensureSuspended n t pos more lose succ =
450ensureSuspended n t pos more lose succ =
451 runParser (demandInput >> go) t pos more lose succ
451 runParser (demandInput >> go) t pos more lose succ
452 where go = T.Parser $ \t' pos' more' lose' succ' ->
452 where go = T.Parser $ \t' pos' more' lose' succ' ->
453 if lengthAtLeast pos' n t'
453 if lengthAtLeast pos' n t'
454− then succ' t' pos' more' (substring pos n t')
454+ then succ' t' pos' more' (n, substring pos n t')
455 else runParser (demandInput >> go) t' pos' more' lose' succ'
455 else runParser (demandInput >> go) t' pos' more' lose' succ'
457-- | If at least @n@ elements of input are available, return the
457-- | If at least @n@ elements of input are available, return the
458-- current input, otherwise fail.
458-- current input, otherwise fail.
459−ensure :: Int -> Parser Text
459+ensure :: Int -> Parser (Int, Text)
460ensure n = T.Parser $ \t pos more lose succ ->
460ensure n = T.Parser $ \t pos more lose succ ->
461 if lengthAtLeast pos n t
461 if lengthAtLeast pos n t
462− then succ t pos more (substring pos n t)
462+ then succ t pos more (n, substring pos n t)
463 -- The uncommon case is kept out-of-line to reduce code size:
463 -- The uncommon case is kept out-of-line to reduce code size:
464 else ensureSuspended n t pos more lose succ
464 else ensureSuspended n t pos more lose succ
465-- Non-recursive so the bounds check can be inlined:
465-- Non-recursive so the bounds check can be inlined: