packages feed

bytesmith 0.3.11.0 → 0.3.11.1

raw patch · 17 files changed

+3814/−3270 lines, 17 filesdep −run-stdep ~byteslicedep ~bytestringsetup-changednew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies removed: run-st

Dependency ranges changed: byteslice, bytestring

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for bytesmith +## 0.3.11.1 -- 2024-02-28++* Update package metadata.+* Remove dependency on `run-st` library.+ ## 0.3.11.0 -- 2024-01-05  * Add `Data.Bytes.Parser.Latin.hexWord32`.
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
bench/Main.hs view
@@ -4,24 +4,28 @@ import Data.Char (ord) import Data.Primitive (ByteArray) import Data.Word (Word8)-import Gauge.Main (defaultMain,bench,whnf)+import Gauge.Main (bench, defaultMain, whnf)  import qualified Data.Bytes.Parser as P import qualified Data.Bytes.Parser.Latin as Latin import qualified GHC.Exts as Exts  main :: IO ()-main = defaultMain-  [ bench "decPositiveInteger" $ whnf-      (\x -> P.parseByteArray (Latin.decUnsignedInteger ()) x)-      encodedBigNumber-  ]+main =+  defaultMain+    [ bench "decPositiveInteger" $+        whnf+          (\x -> P.parseByteArray (Latin.decUnsignedInteger ()) x)+          encodedBigNumber+    ]  encodedBigNumber :: ByteArray-encodedBigNumber = stringToByteArray $ show $ id @Integer $-  246246357264327645234627753190240202405243024304504230544-  *-  732345623640035232405249305932503920593209520932095234651+encodedBigNumber =+  stringToByteArray $+    show $+      id @Integer $+        246246357264327645234627753190240202405243024304504230544+          * 732345623640035232405249305932503920593209520932095234651  stringToByteArray :: String -> ByteArray stringToByteArray =
bytesmith.cabal view
@@ -1,79 +1,88 @@-cabal-version: 2.2-name: bytesmith-version: 0.3.11.0-synopsis: Nonresumable byte parser+cabal-version:   3.0+name:            bytesmith+version:         0.3.11.1+synopsis:        Nonresumable byte parser description:   Parse bytes as fast as possible. This is a nonresumable parser   that aggresively uses `UnboxedSums` to avoid performing any   allocations.-homepage: https://github.com/andrewthad/bytesmith-bug-reports: https://github.com/andrewthad/bytesmith/issues-license: BSD-3-Clause-license-file: LICENSE-author: Andrew Martin-maintainer: andrew.thaddeus@gmail.com-copyright: 2019 Andrew Martin-category: Data-extra-source-files: CHANGELOG.md-tested-with: GHC == 8.6.5 || == 8.8.4 || == 8.10.7 || == 9.0.2 || == 9.2.5 || == 9.4.3 +homepage:        https://github.com/byteverse/bytesmith+bug-reports:     https://github.com/byteverse/bytesmith/issues+license:         BSD-3-Clause+license-file:    LICENSE+author:          Andrew Martin+maintainer:      amartin@layer3com.com+copyright:       2019 Andrew Martin+category:        Data+extra-doc-files: CHANGELOG.md+tested-with:     GHC ==9.4.8 || ==9.6.3 || ==9.8.1++common build-settings+  default-language: Haskell2010+  ghc-options:      -Wall -Wunused-packages+ library+  import:          build-settings   exposed-modules:     Data.Bytes.Parser-    Data.Bytes.Parser.BigEndian-    Data.Bytes.Parser.LittleEndian     Data.Bytes.Parser.Ascii     Data.Bytes.Parser.Base128+    Data.Bytes.Parser.BigEndian     Data.Bytes.Parser.Latin     Data.Bytes.Parser.Leb128+    Data.Bytes.Parser.LittleEndian     Data.Bytes.Parser.Rebindable     Data.Bytes.Parser.Unsafe     Data.Bytes.Parser.Utf8+   other-modules:     Data.Bytes.Parser.Internal     Data.Bytes.Parser.Types+   build-depends:-    , base >=4.12 && <5-    , byteslice >=0.2.6 && <0.3-    , bytestring >=0.10.8 && <=0.12-    , contiguous >= 0.6 && < 0.7-    , natural-arithmetic >=0.1.3-    , primitive >=0.7 && <0.10-    , run-st >=0.1 && <0.2-    , text-short >=0.1.3 && <0.2-    , wide-word >=0.1.0.9 && <0.2-  hs-source-dirs: src-  ghc-options: -O2 -Wall-  default-language: Haskell2010+    , base                >=4.12    && <5+    , byteslice           >=0.2.6   && <0.3+    , bytestring          >=0.10.8  && <0.13+    , contiguous          >=0.6     && <0.7+    , natural-arithmetic  >=0.1.3+    , primitive           >=0.7     && <0.10+    , text-short          >=0.1.3   && <0.2+    , wide-word           >=0.1.0.9 && <0.2 +  hs-source-dirs:  src+  ghc-options:     -O2+ test-suite test-  default-language: Haskell2010-  type: exitcode-stdio-1.0+  import:         build-settings+  type:           exitcode-stdio-1.0   hs-source-dirs: test-  main-is: Main.hs-  ghc-options: -Wall -O2+  main-is:        Main.hs   build-depends:-    , base >=4.12.0.0 && <5+    , base              >=4.12.0.0 && <5+    , byte-order+    , byteslice     , bytesmith     , primitive-    , byteslice-    , tasty-hunit     , tasty+    , tasty-hunit     , tasty-quickcheck-    , byte-order     , text-short     , wide-word  benchmark bench-  type: exitcode-stdio-1.0+  import:         build-settings+  type:           exitcode-stdio-1.0   build-depends:     , base-    , byteslice-    , bytestring+    , bytesmith     , gauge     , primitive-    , bytesmith-  ghc-options: -Wall -O2-  default-language: Haskell2010++  ghc-options:    -O2   hs-source-dirs: bench-  main-is: Main.hs+  main-is:        Main.hs++source-repository head+  type:     git+  location: git://github.com/byteverse/bytesmith.git
src/Data/Bytes/Parser.hs view
@@ -1,90 +1,104 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}-{-# language CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UnboxedTuples #-} --- | Parse non-resumable sequence of bytes. To parse a byte sequence--- as text, use the @Ascii@, @Latin@, and @Utf8@ modules instead.--- Functions for parsing decimal-encoded numbers are found in those--- modules.+{- | Parse non-resumable sequence of bytes. To parse a byte sequence+as text, use the @Ascii@, @Latin@, and @Utf8@ modules instead.+Functions for parsing decimal-encoded numbers are found in those+modules.+-} module Data.Bytes.Parser   ( -- * Types     Parser-  , Result(..)-  , Slice(..)+  , Result (..)+  , Slice (..)+     -- * Run Parsers+     -- ** Result   , parseByteArray   , parseBytes   , parseBytesEffectfully   , parseBytesEither   , parseBytesMaybe+     -- * One Byte   , any+     -- * Many Bytes   , take   , takeN   , takeUpTo   , takeWhile   , takeTrailedBy+     -- * Skip   , skipWhile   , skipTrailedBy   , skipTrailedBy2   , skipTrailedBy2#   , skipTrailedBy3#+     -- * Match   , byteArray   , bytes   , satisfy   , satisfyWith   , cstring+     -- * End of Input   , endOfInput   , isEndOfInput   , remaining   , peekRemaining+     -- * Scanning   , scan+     -- * Lookahead   , peek   , peek'+     -- * Control Flow   , fail   , orElse   , annotate   , (<?>)   , mapErrorEffectfully+     -- * Repetition   , replicate+     -- * Subparsing   , delimit   , measure   , measure_   , measure_#+     -- * Lift Effects   , effect+     -- * Box Result   , boxWord32   , boxIntPair+     -- * Unbox Result   , unboxWord32   , unboxIntPair+     -- * Specialized Bind+     -- | Sometimes, GHC ends up building join points in a way that     -- boxes arguments unnecessarily. In this situation, special variants     -- of monadic @>>=@ can be helpful. If @C#@, @I#@, etc. never@@ -96,26 +110,26 @@   , bindFromCharToIntPair   , bindFromMaybeCharToIntPair   , bindFromMaybeCharToLifted+     -- * Specialized Pure   , pureIntPair+     -- * Specialized Fail   , failIntPair   ) where -import Prelude hiding (length,any,fail,takeWhile,take,replicate)+import Prelude hiding (any, fail, length, replicate, take, takeWhile) -import Data.Bytes.Parser.Internal (Parser(..),ST#,unboxBytes)-import Data.Bytes.Parser.Internal (boxBytes,Result#,uneffectful,fail)-import Data.Bytes.Parser.Internal (uneffectful#,uneffectfulInt#)-import Data.Bytes.Parser.Types (Result(Failure,Success),Slice(Slice))-import Data.Bytes.Parser.Unsafe (unconsume,expose,cursor)-import Data.Bytes.Types (Bytes(..),BytesN(BytesN))-import Data.Primitive (ByteArray(..))-import Data.Primitive.Contiguous (Contiguous,Element)+import Data.Bytes.Parser.Internal (Parser (..), Result#, ST#, boxBytes, fail, unboxBytes, uneffectful, uneffectful#, uneffectfulInt#)+import Data.Bytes.Parser.Types (Result (Failure, Success), Slice (Slice))+import Data.Bytes.Parser.Unsafe (cursor, expose, unconsume)+import Data.Bytes.Types (Bytes (..), BytesN (BytesN))+import Data.Primitive (ByteArray (..))+import Data.Primitive.Contiguous (Contiguous, Element) import Foreign.C.String (CString)-import GHC.Exts (Int(I#),Word#,Int#,Char#,runRW#,(+#),(-#),(>=#))-import GHC.ST (ST(..))-import GHC.Word (Word32(W32#),Word8)+import GHC.Exts (Char#, Int (I#), Int#, Word#, runRW#, (+#), (-#), (>=#))+import GHC.ST (ST (..))+import GHC.Word (Word32 (W32#), Word8)  import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Types as Arithmetic@@ -125,49 +139,52 @@ import qualified Data.Primitive.Contiguous as C import qualified GHC.Exts as Exts --- | Parse a byte sequence. This can succeed even if the--- entire slice was not consumed by the parser.+{- | Parse a byte sequence. This can succeed even if the+entire slice was not consumed by the parser.+-} parseBytes :: forall e a. (forall s. Parser e s a) -> Bytes -> Result e a-{-# inline parseBytes #-}+{-# INLINE parseBytes #-} parseBytes p !b = runResultST action-  where+ where   action :: forall s. ST# s (Result# e a)   action s0 = case p @s of     Parser f -> f (unboxBytes b) s0 --- | Variant of 'parseBytesEither' that discards the error message on failure.--- Just like 'parseBytesEither', this does not impose any checks on the length--- of the remaining input.+{- | Variant of 'parseBytesEither' that discards the error message on failure.+Just like 'parseBytesEither', this does not impose any checks on the length+of the remaining input.+-} parseBytesMaybe :: forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a-{-# inline parseBytesMaybe #-}+{-# INLINE parseBytesMaybe #-} parseBytesMaybe p !b = runMaybeST action-  where+ where   action :: forall s. ST# s (Result# e a)   action s0 = case p @s of     Parser f -> f (unboxBytes b) s0 --- | Variant of 'parseBytes' that discards the new offset and the--- remaining length. This does not, however, require the remaining--- length to be zero. Use 'endOfInput' to accomplish that.+{- | Variant of 'parseBytes' that discards the new offset and the+remaining length. This does not, however, require the remaining+length to be zero. Use 'endOfInput' to accomplish that.+-} parseBytesEither :: forall e a. (forall s. Parser e s a) -> Bytes -> Either e a-{-# inline parseBytesEither #-}+{-# INLINE parseBytesEither #-} parseBytesEither p !b = runEitherST action-  where+ where   action :: forall s. ST# s (Result# e a)   action s0 = case p @s of     Parser f -> f (unboxBytes b) s0  -- Similar to runResultST runMaybeST :: (forall s. ST# s (Result# e x)) -> Maybe x-{-# inline runMaybeST #-}-runMaybeST f = case (runRW# (\s0 -> case f s0 of { (# _, r #) -> r })) of+{-# INLINE runMaybeST #-}+runMaybeST f = case (runRW# (\s0 -> case f s0 of (# _, r #) -> r)) of   (# _ | #) -> Nothing   (# | (# x, _, _ #) #) -> Just x  -- Similar to runResultST runEitherST :: (forall s. ST# s (Result# e x)) -> Either e x-{-# inline runEitherST #-}-runEitherST f = case (runRW# (\s0 -> case f s0 of { (# _, r #) -> r })) of+{-# INLINE runEitherST #-}+runEitherST f = case (runRW# (\s0 -> case f s0 of (# _, r #) -> r)) of   (# e | #) -> Left e   (# | (# x, _, _ #) #) -> Right x @@ -177,49 +194,56 @@ -- it avoids the additional boxing that the Success data -- constructor would normally cause. runResultST :: (forall s. ST# s (Result# e x)) -> Result e x-{-# inline runResultST #-}-runResultST f = case (runRW# (\s0 -> case f s0 of { (# _, r #) -> r })) of+{-# INLINE runResultST #-}+runResultST f = case (runRW# (\s0 -> case f s0 of (# _, r #) -> r)) of   (# e | #) -> Failure e   (# | (# x, off, len #) #) -> Success (Slice (I# off) (I# len) x)  -- | Variant of 'parseBytes' that accepts an unsliced 'ByteArray'. parseByteArray :: (forall s. Parser e s a) -> ByteArray -> Result e a-{-# inline parseByteArray #-}+{-# INLINE parseByteArray #-} parseByteArray p b =   parseBytes p (Bytes b 0 (PM.sizeofByteArray b)) --- | Variant of 'parseBytes' that allows the parser to be run--- as part of an existing effectful context.+{- | Variant of 'parseBytes' that allows the parser to be run+as part of an existing effectful context.+-} parseBytesEffectfully :: Parser e s a -> Bytes -> ST s (Result e a)-{-# inline parseBytesEffectfully #-}-parseBytesEffectfully (Parser f) !b = ST-  (\s0 -> case f (unboxBytes b) s0 of-    (# s1, r #) -> (# s1, boxPublicResult r #)-  )+{-# INLINE parseBytesEffectfully #-}+parseBytesEffectfully (Parser f) !b =+  ST+    ( \s0 -> case f (unboxBytes b) s0 of+        (# s1, r #) -> (# s1, boxPublicResult r #)+    )  -- | Lift an effectful computation into a parser. effect :: ST s a -> Parser e s a-{-# inline effect #-}-effect (ST f) = Parser-  ( \(# _, off, len #) s0 -> case f s0 of-    (# s1, a #) -> (# s1, (# | (# a, off, len #) #) #)-  )+{-# INLINE effect #-}+effect (ST f) =+  Parser+    ( \(# _, off, len #) s0 -> case f s0 of+        (# s1, a #) -> (# s1, (# | (# a, off, len #) #) #)+    )  byteArray :: e -> ByteArray -> Parser e s ()-{-# inline byteArray #-}+{-# INLINE byteArray #-} byteArray e !expected = bytes e (B.fromByteArray expected)  -- | Consume input matching the byte sequence. bytes :: e -> Bytes -> Parser e s ()-bytes e !expected = Parser-  ( \actual@(# _, off, len #) s ->-    let r = if B.isPrefixOf expected (boxBytes actual)-          then let !(I# movement) = length expected in-            (# | (# (), off +# movement, len -# movement #) #)-          else (# e | #)-     in (# s, r #)-  )+bytes e !expected =+  Parser+    ( \actual@(# _, off, len #) s ->+        let r =+              if B.isPrefixOf expected (boxBytes actual)+                then+                  let !(I# movement) = length expected+                   in (# | (# (), off +# movement, len -# movement #) #)+                else (# e | #)+         in (# s, r #)+    ) +{- FOURMOLU_DISABLE -} -- | Consume input matching the @NUL@-terminated C String. cstring :: e -> CString -> Parser e s () cstring e (Exts.Ptr ptr0) = Parser@@ -241,6 +265,7 @@               _ -> (# s, (# e | #) #)      in go ptr0 off0 len0   )+{- FOURMOLU_ENABLE -}  infix 0 <?> @@ -248,57 +273,65 @@ (<?>) :: Parser x s a -> e -> Parser e s a (<?>) = annotate --- | Annotate a parser. If the parser fails, the error will---   be returned.+{- | Annotate a parser. If the parser fails, the error will+  be returned.+-} annotate :: Parser x s a -> e -> Parser e s a annotate p e = p `orElse` fail e --- | Consumes and returns the next byte in the input.--- Fails if no characters are left.+{- | Consumes and returns the next byte in the input.+Fails if no characters are left.+-} any :: e -> Parser e s Word8-{-# inline any #-}-any e = uneffectful $ \chunk -> if length chunk > 0-  then-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8-     in Internal.Success w (offset chunk + 1) (length chunk - 1)-  else Internal.Failure e+{-# INLINE any #-}+any e = uneffectful $ \chunk ->+  if length chunk > 0+    then+      let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+       in Internal.Success w (offset chunk + 1) (length chunk - 1)+    else Internal.Failure e --- | Match any byte, to perform lookahead. Returns 'Nothing' if---   end of input has been reached. Does not consume any input.------   /Note/: Because this parser does not fail, do not use it---   with combinators such as 'many', because such as 'many',---   because such parsers loop until a failure occurs. Careless---   use will thus result in an infinite loop.+{- | Match any byte, to perform lookahead. Returns 'Nothing' if+  end of input has been reached. Does not consume any input.++  /Note/: Because this parser does not fail, do not use it+  with combinators such as 'many', because such as 'many',+  because such parsers loop until a failure occurs. Careless+  use will thus result in an infinite loop.+-} peek :: Parser e s (Maybe Word8)-{-# inline peek #-}+{-# INLINE peek #-} peek = uneffectful $ \chunk ->-  let v = if length chunk > 0-        then Just (B.unsafeIndex chunk 0)-        else Nothing-  in Internal.Success v (offset chunk) (length chunk)+  let v =+        if length chunk > 0+          then Just (B.unsafeIndex chunk 0)+          else Nothing+   in Internal.Success v (offset chunk) (length chunk) --- | Match any byte, to perform lookahead. Does not consume any---   input, but will fail if end of input has been reached.+{- | Match any byte, to perform lookahead. Does not consume any+  input, but will fail if end of input has been reached.+-} peek' :: e -> Parser e s Word8-{-# inline peek' #-}-peek' e = uneffectful $ \chunk -> if length chunk > 0-  then Internal.Success (B.unsafeIndex chunk 0) (offset chunk) (length chunk)-  else Internal.Failure e+{-# INLINE peek' #-}+peek' e = uneffectful $ \chunk ->+  if length chunk > 0+    then Internal.Success (B.unsafeIndex chunk 0) (offset chunk) (length chunk)+    else Internal.Failure e --- | A stateful scanner. The predicate consumes and transforms a---   state argument, and each transformed state is passed to---   successive invocations of the predicate on each byte of the input---   until one returns 'Nothing' or the input ends.------   This parser does not fail. It will return the initial state---   if the predicate returns 'Nothing' on the first byte of input.------   /Note/: Because this parser does not fail, do not use it with---   combinators such a 'many', because such parsers loop until a---   failure occurs. Careless use will thus result in an infinite loop.+{- | A stateful scanner. The predicate consumes and transforms a+  state argument, and each transformed state is passed to+  successive invocations of the predicate on each byte of the input+  until one returns 'Nothing' or the input ends.++  This parser does not fail. It will return the initial state+  if the predicate returns 'Nothing' on the first byte of input.++  /Note/: Because this parser does not fail, do not use it with+  combinators such a 'many', because such parsers loop until a+  failure occurs. Careless use will thus result in an infinite loop.+-} scan :: state -> (state -> Word8 -> Maybe state) -> Parser e s state-{-# inline scan #-}+{-# INLINE scan #-} scan s0 t = do   let go s = do         mw <- peek@@ -313,26 +346,28 @@ -- Does not check to see if any characters are left. This -- is not exported. anyUnsafe :: Parser e s Word8-{-# inline anyUnsafe #-}+{-# INLINE anyUnsafe #-} anyUnsafe = uneffectful $ \chunk ->   let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8    in Internal.Success w (offset chunk + 1) (length chunk - 1) --- | Take while the predicate is matched. This is always inlined. This--- always succeeds.+{- | Take while the predicate is matched. This is always inlined. This+always succeeds.+-} takeWhile :: (Word8 -> Bool) -> Parser e s Bytes-{-# inline takeWhile #-}+{-# INLINE takeWhile #-} takeWhile f = uneffectful $ \chunk -> case B.takeWhile f chunk of   bs -> Internal.Success bs (offset chunk + length bs) (length chunk - length bs) --- | Take bytes until the specified byte is encountered. Consumes--- the matched byte as well. Fails if the byte is not present.--- Visually, the cursor advancement and resulting @Bytes@ for--- @takeTrailedBy 0x19@ look like this:------ >  0x10 0x13 0x08 0x15 0x19 0x23 0x17 | input--- > |---->---->---->---->----|          | cursor--- > {----*----*----*----}               | result bytes+{- | Take bytes until the specified byte is encountered. Consumes+the matched byte as well. Fails if the byte is not present.+Visually, the cursor advancement and resulting @Bytes@ for+@takeTrailedBy 0x19@ look like this:++>  0x10 0x13 0x08 0x15 0x19 0x23 0x17 | input+> |---->---->---->---->----|          | cursor+> {\----*----*----*----\}               | result bytes+-} takeTrailedBy :: e -> Word8 -> Parser e s Bytes takeTrailedBy e !w = do   !start <- cursor@@ -341,107 +376,129 @@   !arr <- expose   pure (Bytes arr start (end - (start + 1))) --- | Skip all characters until the character from the is encountered--- and then consume the matching byte as well.+{- | Skip all characters until the character from the is encountered+and then consume the matching byte as well.+-} skipTrailedBy :: e -> Word8 -> Parser e s ()-{-# inline skipTrailedBy #-}+{-# INLINE skipTrailedBy #-} skipTrailedBy e !w = uneffectful# (\c -> skipUntilConsumeByteLoop e w c)  skipUntilConsumeByteLoop ::-     e -- Error message-  -> Word8 -- byte to match-  -> Bytes -- Chunk-  -> Result# e ()-skipUntilConsumeByteLoop e !w !c = if length c > 0-  then if PM.indexByteArray (array c) (offset c) /= (w :: Word8)-    then skipUntilConsumeByteLoop e w (B.unsafeDrop 1 c)-    else (# | (# (), unI (offset c + 1), unI (length c - 1) #) #)-  else (# e | #)+  e -> -- Error message+  Word8 -> -- byte to match+  Bytes -> -- Chunk+  Result# e ()+skipUntilConsumeByteLoop e !w !c =+  if length c > 0+    then+      if PM.indexByteArray (array c) (offset c) /= (w :: Word8)+        then skipUntilConsumeByteLoop e w (B.unsafeDrop 1 c)+        else (# | (# (), unI (offset c + 1), unI (length c - 1) #) #)+    else (# e | #) --- | Skip all bytes until either of the bytes in encountered. Then,--- consume the matched byte. @True@ indicates that the first argument--- byte was encountered. @False@ indicates that the second argument--- byte was encountered.+{- | Skip all bytes until either of the bytes in encountered. Then,+consume the matched byte. @True@ indicates that the first argument+byte was encountered. @False@ indicates that the second argument+byte was encountered.+-} skipTrailedBy2 ::-     e -- ^ Error message-  -> Word8 -- ^ First trailer, @False@ indicates that this was encountered-  -> Word8 -- ^ Second trailer, @True@ indicates that this was encountered-  -> Parser e s Bool-{-# inline skipTrailedBy2 #-}+  -- | Error message+  e ->+  -- | First trailer, @False@ indicates that this was encountered+  Word8 ->+  -- | Second trailer, @True@ indicates that this was encountered+  Word8 ->+  Parser e s Bool+{-# INLINE skipTrailedBy2 #-} skipTrailedBy2 e !wa !wb = boxBool (skipTrailedBy2# e wa wb)  skipTrailedBy2# ::-     e -- ^ Error message-  -> Word8 -- ^ First trailer, 0 indicates that this was encountered-  -> Word8 -- ^ Second trailer, 1 indicates that this was encountered-  -> Parser e s Int#-{-# inline skipTrailedBy2# #-}+  -- | Error message+  e ->+  -- | First trailer, 0 indicates that this was encountered+  Word8 ->+  -- | Second trailer, 1 indicates that this was encountered+  Word8 ->+  Parser e s Int#+{-# INLINE skipTrailedBy2# #-} skipTrailedBy2# e !wa !wb =   uneffectfulInt# (\c -> skipUntilConsumeByteEitherLoop e wa wb c)  skipTrailedBy3# ::-     e -- ^ Error message-  -> Word8 -- ^ First trailer, 0 indicates that this was encountered-  -> Word8 -- ^ Second trailer, 1 indicates that this was encountered-  -> Word8 -- ^ Third trailer, 2 indicates that this was encountered-  -> Parser e s Int#-{-# inline skipTrailedBy3# #-}+  -- | Error message+  e ->+  -- | First trailer, 0 indicates that this was encountered+  Word8 ->+  -- | Second trailer, 1 indicates that this was encountered+  Word8 ->+  -- | Third trailer, 2 indicates that this was encountered+  Word8 ->+  Parser e s Int#+{-# INLINE skipTrailedBy3# #-} skipTrailedBy3# e !wa !wb !wc =   uneffectfulInt# (\c -> skipUntilConsumeByte3Loop e wa wb wc c)  skipUntilConsumeByteEitherLoop ::-     e -- Error message-  -> Word8 -- first trailer-  -> Word8 -- second trailer-  -> Bytes -- Chunk-  -> Result# e Int#-skipUntilConsumeByteEitherLoop e !wa !wb !c = if length c > 0-  then let byte = PM.indexByteArray (array c) (offset c) in-    if | byte == wa -> (# | (# 0#, unI (offset c + 1), unI (length c - 1) #) #)-       | byte == wb -> (# | (# 1#, unI (offset c + 1), unI (length c - 1) #) #)-       | otherwise -> skipUntilConsumeByteEitherLoop e wa wb (B.unsafeDrop 1 c)-  else (# e | #)+  e -> -- Error message+  Word8 -> -- first trailer+  Word8 -> -- second trailer+  Bytes -> -- Chunk+  Result# e Int#+skipUntilConsumeByteEitherLoop e !wa !wb !c =+  if length c > 0+    then+      let byte = PM.indexByteArray (array c) (offset c)+       in if+            | byte == wa -> (# | (# 0#, unI (offset c + 1), unI (length c - 1) #) #)+            | byte == wb -> (# | (# 1#, unI (offset c + 1), unI (length c - 1) #) #)+            | otherwise -> skipUntilConsumeByteEitherLoop e wa wb (B.unsafeDrop 1 c)+    else (# e | #)  skipUntilConsumeByte3Loop ::-     e -- Error message-  -> Word8 -- first trailer-  -> Word8 -- second trailer-  -> Word8 -- third trailer-  -> Bytes -- Chunk-  -> Result# e Int#-skipUntilConsumeByte3Loop e !wa !wb !wc !c = if length c > 0-  then let byte = PM.indexByteArray (array c) (offset c) in-    if | byte == wa -> (# | (# 0#, unI (offset c + 1), unI (length c - 1) #) #)-       | byte == wb -> (# | (# 1#, unI (offset c + 1), unI (length c - 1) #) #)-       | byte == wc -> (# | (# 2#, unI (offset c + 1), unI (length c - 1) #) #)-       | otherwise -> skipUntilConsumeByte3Loop e wa wb wc (B.unsafeDrop 1 c)-  else (# e | #)+  e -> -- Error message+  Word8 -> -- first trailer+  Word8 -> -- second trailer+  Word8 -> -- third trailer+  Bytes -> -- Chunk+  Result# e Int#+skipUntilConsumeByte3Loop e !wa !wb !wc !c =+  if length c > 0+    then+      let byte = PM.indexByteArray (array c) (offset c)+       in if+            | byte == wa -> (# | (# 0#, unI (offset c + 1), unI (length c - 1) #) #)+            | byte == wb -> (# | (# 1#, unI (offset c + 1), unI (length c - 1) #) #)+            | byte == wc -> (# | (# 2#, unI (offset c + 1), unI (length c - 1) #) #)+            | otherwise -> skipUntilConsumeByte3Loop e wa wb wc (B.unsafeDrop 1 c)+    else (# e | #) --- | Take the given number of bytes. Fails if there is not enough---   remaining input.+{- | Take the given number of bytes. Fails if there is not enough+  remaining input.+-} take :: e -> Int -> Parser e s Bytes-{-# inline take #-}-take e n = uneffectful $ \chunk -> if n <= B.length chunk-  then case B.unsafeTake n chunk of-    bs -> Internal.Success bs (offset chunk + n) (length chunk - n)-  else Internal.Failure e+{-# INLINE take #-}+take e n = uneffectful $ \chunk ->+  if n <= B.length chunk+    then case B.unsafeTake n chunk of+      bs -> Internal.Success bs (offset chunk + n) (length chunk - n)+    else Internal.Failure e  -- | Variant of 'take' that tracks the length of the result in the result type. takeN :: e -> Arithmetic.Nat n -> Parser e s (BytesN n)-takeN e n0 = uneffectful $ \chunk -> if n <= B.length chunk-  then case B.unsafeTake n chunk of-    Bytes theChunk theOff _ -> Internal.Success (BytesN theChunk theOff) (offset chunk + n) (length chunk - n)-  else Internal.Failure e-  where+takeN e n0 = uneffectful $ \chunk ->+  if n <= B.length chunk+    then case B.unsafeTake n chunk of+      Bytes theChunk theOff _ -> Internal.Success (BytesN theChunk theOff) (offset chunk + n) (length chunk - n)+    else Internal.Failure e+ where   !n = Nat.demote n0 ----- | Take at most the given number of bytes. This is greedy. It will---   consume as many bytes as there are available until it has consumed---   @n@ bytes. This never fails.+{- | Take at most the given number of bytes. This is greedy. It will+  consume as many bytes as there are available until it has consumed+  @n@ bytes. This never fails.+-} takeUpTo :: Int -> Parser e s Bytes-{-# inline takeUpTo #-}+{-# INLINE takeUpTo #-} takeUpTo n = uneffectful $ \chunk ->   let m = min n (B.length chunk)    in case B.unsafeTake m chunk of@@ -449,68 +506,76 @@  -- | Consume all remaining bytes in the input. remaining :: Parser e s Bytes-{-# inline remaining #-}+{-# INLINE remaining #-} remaining = uneffectful $ \chunk ->   Internal.Success chunk (offset chunk + length chunk) 0  -- | Return all remaining bytes in the input without consuming them. peekRemaining :: Parser e s Bytes-{-# inline peekRemaining #-}+{-# INLINE peekRemaining #-} peekRemaining = uneffectful $ \b@(Bytes _ off len) ->   Internal.Success b off len  -- | Skip while the predicate is matched. This is always inlined. skipWhile :: (Word8 -> Bool) -> Parser e s ()-{-# inline skipWhile #-}-skipWhile f = go where-  go = isEndOfInput >>= \case-    True -> pure ()-    False -> do-      w <- anyUnsafe-      if f w-        then go-        else unconsume 1+{-# INLINE skipWhile #-}+skipWhile f = go+ where+  go =+    isEndOfInput >>= \case+      True -> pure ()+      False -> do+        w <- anyUnsafe+        if f w+          then go+          else unconsume 1 --- | The parser @satisfy p@ succeeds for any byte for which the---   predicate @p@ returns 'True'. Returns the byte that is---   actually parsed.+{- | The parser @satisfy p@ succeeds for any byte for which the+  predicate @p@ returns 'True'. Returns the byte that is+  actually parsed.+-} satisfy :: e -> (Word8 -> Bool) -> Parser e s Word8 satisfy e p = satisfyWith e id p-{-# inline satisfy #-}+{-# INLINE satisfy #-} --- | The parser @satisfyWith f p@ transforms a byte, and succeeds---   if the predicate @p@ returns 'True' on the transformed value.---   The parser returns the transformed byte that was parsed.+{- | The parser @satisfyWith f p@ transforms a byte, and succeeds+  if the predicate @p@ returns 'True' on the transformed value.+  The parser returns the transformed byte that was parsed.+-} satisfyWith :: e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a-{-# inline satisfyWith #-}-satisfyWith e f p = uneffectful $ \chunk -> if length chunk > 0-  then case B.unsafeIndex chunk 0 of-    w ->-      let v = f w-      in if p v-        then Internal.Success v (offset chunk + 1) (length chunk - 1)-        else Internal.Failure e-  else Internal.Failure e+{-# INLINE satisfyWith #-}+satisfyWith e f p = uneffectful $ \chunk ->+  if length chunk > 0+    then case B.unsafeIndex chunk 0 of+      w ->+        let v = f w+         in if p v+              then Internal.Success v (offset chunk + 1) (length chunk - 1)+              else Internal.Failure e+    else Internal.Failure e  -- | Fails if there is still more input remaining. endOfInput :: e -> Parser e s ()-{-# inline endOfInput #-}-endOfInput e = uneffectful $ \chunk -> if length chunk == 0-  then Internal.Success () (offset chunk) 0-  else Internal.Failure e+{-# INLINE endOfInput #-}+endOfInput e = uneffectful $ \chunk ->+  if length chunk == 0+    then Internal.Success () (offset chunk) 0+    else Internal.Failure e --- | Returns true if there are no more bytes in the input. Returns--- false otherwise. Always succeeds.+{- | Returns true if there are no more bytes in the input. Returns+false otherwise. Always succeeds.+-} isEndOfInput :: Parser e s Bool-{-# inline isEndOfInput #-}+{-# INLINE isEndOfInput #-} isEndOfInput = uneffectful $ \chunk ->   Internal.Success (length chunk == 0) (offset chunk) (length chunk)  boxPublicResult :: Result# e a -> Result e a-{-# inline boxPublicResult #-}+{-# INLINE boxPublicResult #-} boxPublicResult (# | (# a, b, c #) #) = Success (Slice (I# b) (I# c) a) boxPublicResult (# e | #) = Failure e +{- FOURMOLU_DISABLE -} -- | Convert a 'Word32' parser to a 'Word#' parser. unboxWord32 :: Parser e s Word32 -> Parser e s Word# {-# inline unboxWord32 #-}@@ -524,17 +589,20 @@ #endif         a, b, c #) #) #)   )+{- FOURMOLU_ENABLE -}  -- | Convert a @(Int,Int)@ parser to a @(# Int#, Int# #)@ parser.-unboxIntPair :: Parser e s (Int,Int) -> Parser e s (# Int#, Int# #)-{-# inline unboxIntPair #-}-unboxIntPair (Parser f) = Parser-  (\x s0 -> case f x s0 of-    (# s1, r #) -> case r of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# (I# y, I# z), b, c #) #) -> (# s1, (# | (# (# y, z #), b, c #) #) #)-  )+unboxIntPair :: Parser e s (Int, Int) -> Parser e s (# Int#, Int# #)+{-# INLINE unboxIntPair #-}+unboxIntPair (Parser f) =+  Parser+    ( \x s0 -> case f x s0 of+        (# s1, r #) -> case r of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# (I# y, I# z), b, c #) #) -> (# s1, (# | (# (# y, z #), b, c #) #) #)+    ) +{- FOURMOLU_DISABLE -} -- | Convert a 'Word#' parser to a 'Word32' parser. Precondition: -- the argument parser only returns words less than 4294967296. boxWord32 :: Parser e s Word# -> Parser e s Word32@@ -549,233 +617,263 @@ #endif         a), b, c #) #) #)   )+{- FOURMOLU_ENABLE -}  -- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser. boxInt :: Parser e s Int# -> Parser e s Int-{-# inline boxInt #-}-boxInt (Parser f) = Parser-  (\x s0 -> case f x s0 of-    (# s1, r #) -> case r of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) -> (# s1, (# | (# I# y, b, c #) #) #)-  )+{-# INLINE boxInt #-}+boxInt (Parser f) =+  Parser+    ( \x s0 -> case f x s0 of+        (# s1, r #) -> case r of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) -> (# s1, (# | (# I# y, b, c #) #) #)+    )  -- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser. boxBool :: Parser e s Int# -> Parser e s Bool-{-# inline boxBool #-}-boxBool (Parser f) = Parser-  (\x s0 -> case f x s0 of-    (# s1, r #) -> case r of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) -> (# s1, (# | (# case y of {1# -> True; _ -> False}, b, c #) #) #)-  )+{-# INLINE boxBool #-}+boxBool (Parser f) =+  Parser+    ( \x s0 -> case f x s0 of+        (# s1, r #) -> case r of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) -> (# s1, (# | (# case y of 1# -> True; _ -> False, b, c #) #) #)+    )  -- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.-boxIntPair :: Parser e s (# Int#, Int# #) -> Parser e s (Int,Int)-{-# inline boxIntPair #-}-boxIntPair (Parser f) = Parser-  (\x s0 -> case f x s0 of-    (# s1, r #) -> case r of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# (# y, z #), b, c #) #) -> (# s1, (# | (# (I# y, I# z), b, c #) #) #)-  )-+boxIntPair :: Parser e s (# Int#, Int# #) -> Parser e s (Int, Int)+{-# INLINE boxIntPair #-}+boxIntPair (Parser f) =+  Parser+    ( \x s0 -> case f x s0 of+        (# s1, r #) -> case r of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# (# y, z #), b, c #) #) -> (# s1, (# | (# (I# y, I# z), b, c #) #) #)+    ) --- | There is a law-abiding instance of 'Alternative' for 'Parser'.--- However, it is not terribly useful since error messages seldom--- have a 'Monoid' instance. This function is a variant of @\<|\>@--- that is right-biased in its treatment of error messages.--- Consequently, @orElse@ lacks an identity.--- See <https://github.com/bos/attoparsec/issues/122 attoparsec issue #122>--- for more discussion of this topic.+{- | There is a law-abiding instance of 'Alternative' for 'Parser'.+However, it is not terribly useful since error messages seldom+have a 'Monoid' instance. This function is a variant of @\<|\>@+that is right-biased in its treatment of error messages.+Consequently, @orElse@ lacks an identity.+See <https://github.com/bos/attoparsec/issues/122 attoparsec issue #122>+for more discussion of this topic.+-} infixl 3 `orElse`+ orElse :: Parser x s a -> Parser e s a -> Parser e s a-{-# inline orElse #-}-orElse (Parser f) (Parser g) = Parser-  (\x s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# _ | #) -> g x s1-      (# | r #) -> (# s1, (# | r #) #)-  )+{-# INLINE orElse #-}+orElse (Parser f) (Parser g) =+  Parser+    ( \x s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# _ | #) -> g x s1+          (# | r #) -> (# s1, (# | r #) #)+    )  -- | Effectfully adjusts the error message if an error occurs. mapErrorEffectfully :: (e1 -> ST s e2) -> Parser e1 s a -> Parser e2 s a-{-# inline mapErrorEffectfully #-}-mapErrorEffectfully f (Parser g) = Parser-  (\x s0 -> case g x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> case f e of-        ST h -> case h s1 of-          (# s2, e' #) -> (# s2, (# e' | #) #)-      (# | r #) -> (# s1, (# | r #) #)-  )+{-# INLINE mapErrorEffectfully #-}+mapErrorEffectfully f (Parser g) =+  Parser+    ( \x s0 -> case g x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> case f e of+            ST h -> case h s1 of+              (# s2, e' #) -> (# s2, (# e' | #) #)+          (# | r #) -> (# s1, (# | r #) #)+    )  bindFromCharToLifted :: Parser s e Char# -> (Char# -> Parser s e a) -> Parser s e a-{-# inline bindFromCharToLifted #-}-bindFromCharToLifted (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindFromCharToLifted #-}+bindFromCharToLifted (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  bindFromCharToIntPair :: Parser s e Char# -> (Char# -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)-{-# inline bindFromCharToIntPair #-}-bindFromCharToIntPair (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindFromCharToIntPair #-}+bindFromCharToIntPair (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  bindFromLiftedToInt :: Parser s e a -> (a -> Parser s e Int#) -> Parser s e Int#-{-# inline bindFromLiftedToInt #-}-bindFromLiftedToInt (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindFromLiftedToInt #-}+bindFromLiftedToInt (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  bindFromLiftedToIntPair :: Parser s e a -> (a -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)-{-# inline bindFromLiftedToIntPair #-}-bindFromLiftedToIntPair (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindFromLiftedToIntPair #-}+bindFromLiftedToIntPair (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  bindFromIntToIntPair :: Parser s e Int# -> (Int# -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)-{-# inline bindFromIntToIntPair #-}-bindFromIntToIntPair (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindFromIntToIntPair #-}+bindFromIntToIntPair (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  bindFromMaybeCharToIntPair ::-     Parser s e (# (# #) | Char# #)-  -> ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #))-  -> Parser s e (# Int#, Int# #)-{-# inline bindFromMaybeCharToIntPair #-}-bindFromMaybeCharToIntPair (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  Parser s e (# (# #) | Char# #) ->+  ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #)) ->+  Parser s e (# Int#, Int# #)+{-# INLINE bindFromMaybeCharToIntPair #-}+bindFromMaybeCharToIntPair (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  bindFromMaybeCharToLifted ::-     Parser s e (# (# #) | Char# #)-  -> ((# (# #) | Char# #) -> Parser s e a)-  -> Parser s e a-{-# inline bindFromMaybeCharToLifted #-}-bindFromMaybeCharToLifted (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  Parser s e (# (# #) | Char# #) ->+  ((# (# #) | Char# #) -> Parser s e a) ->+  Parser s e a+{-# INLINE bindFromMaybeCharToLifted #-}+bindFromMaybeCharToLifted (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  pureIntPair ::-     (# Int#, Int# #)-  -> Parser s e (# Int#, Int# #)-{-# inline pureIntPair #-}-pureIntPair a = Parser-  (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))+  (# Int#, Int# #) ->+  Parser s e (# Int#, Int# #)+{-# INLINE pureIntPair #-}+pureIntPair a =+  Parser+    (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))  failIntPair :: e -> Parser e s (# Int#, Int# #)-{-# inline failIntPair #-}-failIntPair e = Parser-  (\(# _, _, _ #) s -> (# s, (# e | #) #))+{-# INLINE failIntPair #-}+failIntPair e =+  Parser+    (\(# _, _, _ #) s -> (# s, (# e | #) #)) --- | Augment a parser with the number of bytes that were consume while--- it executed.-measure :: Parser e s a -> Parser e s (Int,a)-{-# inline measure #-}-measure (Parser f) = Parser-  (\x@(# _, pre, _ #) s0 -> case f x s0 of-    (# s1, r #) -> case r of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, post, c #) #) -> (# s1, (# | (# (I# (post -# pre), y),post,c #) #) #)-  )+{- | Augment a parser with the number of bytes that were consume while+it executed.+-}+measure :: Parser e s a -> Parser e s (Int, a)+{-# INLINE measure #-}+measure (Parser f) =+  Parser+    ( \x@(# _, pre, _ #) s0 -> case f x s0 of+        (# s1, r #) -> case r of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, post, c #) #) -> (# s1, (# | (# (I# (post -# pre), y), post, c #) #) #)+    ) --- | Run a parser and discard the result, returning instead the number--- of bytes that the parser consumed.+{- | Run a parser and discard the result, returning instead the number+of bytes that the parser consumed.+-} measure_ :: Parser e s a -> Parser e s Int-{-# inline measure_ #-}+{-# INLINE measure_ #-} measure_ p = boxInt (measure_# p)  -- | Variant of 'measure_' with an unboxed result. measure_# :: Parser e s a -> Parser e s Int#-{-# inline measure_# #-}-measure_# (Parser f) = Parser-  (\x@(# _, pre, _ #) s0 -> case f x s0 of-    (# s1, r #) -> case r of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, post, c #) #) -> (# s1, (# | (# post -# pre,post,c #) #) #)-  )-+{-# INLINE measure_# #-}+measure_# (Parser f) =+  Parser+    ( \x@(# _, pre, _ #) s0 -> case f x s0 of+        (# s1, r #) -> case r of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, post, c #) #) -> (# s1, (# | (# post -# pre, post, c #) #) #)+    ) +{- | Run a parser in a delimited context, failing if the requested number+of bytes are not available or if the delimited parser does not+consume all input. This combinator can be understood as a composition+of 'take', 'effect', 'parseBytesEffectfully', and 'endOfInput'. It is+provided as a single combinator because for convenience and because it is+easy to make mistakes when manually assembling the aforementioned parsers.+The pattern of prefixing an encoding with its length is common.+This is discussed more in+<https://github.com/bos/attoparsec/issues/129 attoparsec issue #129>. --- | Run a parser in a delimited context, failing if the requested number--- of bytes are not available or if the delimited parser does not--- consume all input. This combinator can be understood as a composition--- of 'take', 'effect', 'parseBytesEffectfully', and 'endOfInput'. It is--- provided as a single combinator because for convenience and because it is--- easy to make mistakes when manually assembling the aforementioned parsers.--- The pattern of prefixing an encoding with its length is common.--- This is discussed more in--- <https://github.com/bos/attoparsec/issues/129 attoparsec issue #129>.------ > delimit e1 e2 n remaining === take e1 n+> delimit e1 e2 n remaining === take e1 n+-} delimit ::-     e -- ^ Error message when not enough bytes are present-  -> e -- ^ Error message when delimited parser does not consume all input-  -> Int -- ^ Exact number of bytes delimited parser is expected to consume-  -> Parser e s a -- ^ Parser to execute in delimited context-  -> Parser e s a-{-# inline delimit #-}-delimit esz eleftovers (I# n) (Parser f) = Parser-  ( \(# arr, off, len #) s0 -> case len >=# n of-    1# -> case f (# arr, off, n #) s0 of-      (# s1, r #) -> case r of-        (# e | #) -> (# s1, (# e | #) #)-        (# | (# a, newOff, leftovers #) #) -> case leftovers of-          0# -> (# s1, (# | (# a, newOff, len -# n #) #) #)-          _ -> (# s1, (# eleftovers | #) #)-    _ -> (# s0, (# esz | #) #)-  )+  -- | Error message when not enough bytes are present+  e ->+  -- | Error message when delimited parser does not consume all input+  e ->+  -- | Exact number of bytes delimited parser is expected to consume+  Int ->+  -- | Parser to execute in delimited context+  Parser e s a ->+  Parser e s a+{-# INLINE delimit #-}+delimit esz eleftovers (I# n) (Parser f) =+  Parser+    ( \(# arr, off, len #) s0 -> case len >=# n of+        1# -> case f (# arr, off, n #) s0 of+          (# s1, r #) -> case r of+            (# e | #) -> (# s1, (# e | #) #)+            (# | (# a, newOff, leftovers #) #) -> case leftovers of+              0# -> (# s1, (# | (# a, newOff, len -# n #) #) #)+              _ -> (# s1, (# eleftovers | #) #)+        _ -> (# s0, (# esz | #) #)+    ) --- | Replicate a parser @n@ times, writing the results into--- an array of length @n@. For @Array@ and @SmallArray@, this--- is lazy in the elements, so be sure the they result of the--- parser is evaluated appropriately to avoid unwanted thunks.-replicate :: forall arr e s a. (Contiguous arr, Element arr a)-  => Int -- ^ Number of times to run the parser-  -> Parser e s a -- ^ Parser-  -> Parser e s (arr a)-{-# inline replicate #-}+{- | Replicate a parser @n@ times, writing the results into+an array of length @n@. For @Array@ and @SmallArray@, this+is lazy in the elements, so be sure the they result of the+parser is evaluated appropriately to avoid unwanted thunks.+-}+replicate ::+  forall arr e s a.+  (Contiguous arr, Element arr a) =>+  -- | Number of times to run the parser+  Int ->+  -- | Parser+  Parser e s a ->+  Parser e s (arr a)+{-# INLINE replicate #-} replicate !len p = do   marr <- effect (C.new len)   let go :: Int -> Parser e s (arr a)-      go !ix = if ix < len-        then do-          a <- p-          effect (C.write marr ix a)-          go (ix + 1)-        else effect (C.unsafeFreeze marr)+      go !ix =+        if ix < len+          then do+            a <- p+            effect (C.write marr ix a)+            go (ix + 1)+          else effect (C.unsafeFreeze marr)   go 0  unI :: Int -> Int#-{-# inline unI #-}+{-# INLINE unI #-} unI (I# w) = w
src/Data/Bytes/Parser/Ascii.hs view
@@ -1,41 +1,40 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UnboxedTuples #-} --- | Parse input as ASCII-encoded text. Some parsers in this module,--- like 'any' and 'peek', fail if they encounter a byte above @0x7F@.--- Others, like numeric parsers and skipping parsers, leave the cursor--- at the position of the offending byte without failing.+{- | Parse input as ASCII-encoded text. Some parsers in this module,+like 'any' and 'peek', fail if they encounter a byte above @0x7F@.+Others, like numeric parsers and skipping parsers, leave the cursor+at the position of the offending byte without failing.+-} module Data.Bytes.Parser.Ascii   ( -- * Matching     Latin.char   , Latin.char2   , Latin.char3   , Latin.char4+     -- * Case-Insensitive Matching   , charInsensitive+     -- * Get Character   , any   , any#   , peek   , opt+     -- * Match Many   , shortTrailedBy   , takeShortWhile+     -- * Skip   , Latin.skipDigits   , Latin.skipDigits1@@ -45,6 +44,7 @@   , skipAlpha1   , skipTrailedBy   , skipWhile+     -- * Numbers   , Latin.decWord   , Latin.decWord8@@ -52,47 +52,49 @@   , Latin.decWord32   ) where -import Prelude hiding (length,any,fail,takeWhile)+import Prelude hiding (any, fail, length, takeWhile) +import Control.Monad.ST (runST) import Data.Bits (clearBit)-import Data.Bytes.Types (Bytes(..))-import Data.Bytes.Parser.Internal (Parser(..),uneffectful,Result#,uneffectful#)-import Data.Bytes.Parser.Internal (Result(..),indexLatinCharArray,upcastUnitSuccess)+import Data.Bytes.Parser.Internal (Parser (..), Result (..), Result#, indexLatinCharArray, uneffectful, uneffectful#, upcastUnitSuccess)+import Data.Bytes.Types (Bytes (..)) import Data.Char (ord)-import Data.Word (Word8) import Data.Text.Short (ShortText)-import Control.Monad.ST.Run (runByteArrayST)-import GHC.Exts (Int(I#),Char(C#),Int#,Char#,(-#),(+#),(<#),ord#,indexCharArray#,chr#)-import GHC.Exts (gtChar#)+import Data.Word (Word8)+import GHC.Exts (Char (C#), Char#, Int (I#), Int#, chr#, gtChar#, indexCharArray#, ord#, (+#), (-#), (<#))  import qualified Data.ByteString.Short.Internal as BSS-import qualified Data.Text.Short.Unsafe as TS import qualified Data.Bytes as Bytes import qualified Data.Bytes.Parser.Latin as Latin import qualified Data.Bytes.Parser.Unsafe as Unsafe import qualified Data.Primitive as PM+import qualified Data.Text.Short.Unsafe as TS --- | Consume the next character, failing if it does not match the expected--- value or if there is no more input. This check for equality is case--- insensitive.------ Precondition: The argument must be a letter (@[a-zA-Z]@). Behavior is--- undefined if it is not.+{- | Consume the next character, failing if it does not match the expected+value or if there is no more input. This check for equality is case+insensitive.++Precondition: The argument must be a letter (@[a-zA-Z]@). Behavior is+undefined if it is not.+-} charInsensitive :: e -> Char -> Parser e s ()-{-# inline charInsensitive #-}-charInsensitive e !c = uneffectful $ \chunk -> if length chunk > 0-  then if clearBit (PM.indexByteArray (array chunk) (offset chunk) :: Word8) 5 == w-    then Success () (offset chunk + 1) (length chunk - 1)+{-# INLINE charInsensitive #-}+charInsensitive e !c = uneffectful $ \chunk ->+  if length chunk > 0+    then+      if clearBit (PM.indexByteArray (array chunk) (offset chunk) :: Word8) 5 == w+        then Success () (offset chunk + 1) (length chunk - 1)+        else Failure e     else Failure e-  else Failure e-  where+ where   w = clearBit (fromIntegral @Int @Word8 (ord c)) 5 --- | Consume input until the trailer is found. Then, consume--- the trailer as well. This fails if the trailer is not--- found or if any non-ASCII characters are encountered.+{- | Consume input until the trailer is found. Then, consume+the trailer as well. This fails if the trailer is not+found or if any non-ASCII characters are encountered.+-} skipTrailedBy :: e -> Char -> Parser e s ()-{-# inline skipTrailedBy #-}+{-# INLINE skipTrailedBy #-} skipTrailedBy e !c = do   let go = do         !d <- any e@@ -101,30 +103,32 @@           else go   go --- | Consume characters matching the predicate. The stops when it--- encounters a non-matching character or when it encounters a byte--- above @0x7F@. This never fails.+{- | Consume characters matching the predicate. The stops when it+encounters a non-matching character or when it encounters a byte+above @0x7F@. This never fails.+-} takeShortWhile :: (Char -> Bool) -> Parser e s ShortText-{-# inline takeShortWhile #-}+{-# INLINE takeShortWhile #-} takeShortWhile p = do   !start <- Unsafe.cursor   skipWhile p   end <- Unsafe.cursor   src <- Unsafe.expose   let len = end - start-      !r = runByteArrayST $ do+      !r = runST $ do         marr <- PM.newByteArray len         PM.copyByteArray marr 0 src start len         PM.unsafeFreezeByteArray marr-  pure-    $ TS.fromShortByteStringUnsafe-    $ byteArrayToShortByteString-    $ r+  pure $+    TS.fromShortByteStringUnsafe $+      byteArrayToShortByteString $+        r --- | Consume input through the next occurrence of the target--- character and return the consumed input, excluding the--- target character, as a 'ShortText'. This fails if it--- encounters any bytes above @0x7F@.+{- | Consume input through the next occurrence of the target+character and return the consumed input, excluding the+target character, as a 'ShortText'. This fails if it+encounters any bytes above @0x7F@.+-} shortTrailedBy :: e -> Char -> Parser e s ShortText shortTrailedBy e !c = do   !start <- Unsafe.cursor@@ -132,133 +136,147 @@   end <- Unsafe.cursor   src <- Unsafe.expose   let len = end - start - 1-      !r = runByteArrayST $ do+      !r = runST $ do         marr <- PM.newByteArray len         PM.copyByteArray marr 0 src start len         PM.unsafeFreezeByteArray marr-  pure-    $ TS.fromShortByteStringUnsafe-    $ byteArrayToShortByteString-    $ r-+  pure $+    TS.fromShortByteStringUnsafe $+      byteArrayToShortByteString $+        r  -- | Consumes and returns the next character in the input. any :: e -> Parser e s Char-{-# inline any #-}-any e = uneffectful $ \chunk -> if length chunk > 0-  then-    let c = indexLatinCharArray (array chunk) (offset chunk)-     in if c < '\128'-          then Success c (offset chunk + 1) (length chunk - 1)-          else Failure e-  else Failure e+{-# INLINE any #-}+any e = uneffectful $ \chunk ->+  if length chunk > 0+    then+      let c = indexLatinCharArray (array chunk) (offset chunk)+       in if c < '\128'+            then Success c (offset chunk + 1) (length chunk - 1)+            else Failure e+    else Failure e  -- | Variant of 'any' with unboxed result. any# :: e -> Parser e s Char#-{-# inline any# #-}-any# e = Parser-  (\(# arr, off, len #) s0 -> case len of-    0# -> (# s0, (# e | #) #)-    _ ->-      let !w = indexCharArray# arr off-       in case ord# w <# 128# of-            1# -> (# s0, (# | (# w, off +# 1#, len -# 1# #) #) #)-            _ -> (# s0, (# e | #) #)-  )+{-# INLINE any# #-}+any# e =+  Parser+    ( \(# arr, off, len #) s0 -> case len of+        0# -> (# s0, (# e | #) #)+        _ ->+          let !w = indexCharArray# arr off+           in case ord# w <# 128# of+                1# -> (# s0, (# | (# w, off +# 1#, len -# 1# #) #) #)+                _ -> (# s0, (# e | #) #)+    )  unI :: Int -> Int#-{-# inline unI #-}+{-# INLINE unI #-} unI (I# w) = w --- | Examine the next byte without consuming it, interpret it as an--- ASCII-encoded character. This fails if the byte is above @0x7F@ or--- if the end of input has been reached.+{- | Examine the next byte without consuming it, interpret it as an+ASCII-encoded character. This fails if the byte is above @0x7F@ or+if the end of input has been reached.+-} peek :: e -> Parser e s Char-{-# inline peek #-}-peek e = uneffectful $ \chunk -> if length chunk > 0-  then-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8-     in if w < 128-          then Success-                 (C# (chr# (unI (fromIntegral w))))-                 (offset chunk)-                 (length chunk)-          else Failure e-  else Failure e+{-# INLINE peek #-}+peek e = uneffectful $ \chunk ->+  if length chunk > 0+    then+      let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+       in if w < 128+            then+              Success+                (C# (chr# (unI (fromIntegral w))))+                (offset chunk)+                (length chunk)+            else Failure e+    else Failure e --- | Consume the next byte, interpreting it as an ASCII-encoded character.--- Fails if the byte is above @0x7F@. Returns @Nothing@ if the--- end of the input has been reached.+{- | Consume the next byte, interpreting it as an ASCII-encoded character.+Fails if the byte is above @0x7F@. Returns @Nothing@ if the+end of the input has been reached.+-} opt :: e -> Parser e s (Maybe Char)-{-# inline opt #-}-opt e = uneffectful $ \chunk -> if length chunk > 0-  then-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8-     in if w < 128-          then Success-                 (Just (C# (chr# (unI (fromIntegral w)))))-                 (offset chunk + 1)-                 (length chunk - 1)-          else Failure e-  else Success Nothing (offset chunk) (length chunk)+{-# INLINE opt #-}+opt e = uneffectful $ \chunk ->+  if length chunk > 0+    then+      let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+       in if w < 128+            then+              Success+                (Just (C# (chr# (unI (fromIntegral w)))))+                (offset chunk + 1)+                (length chunk - 1)+            else Failure e+    else Success Nothing (offset chunk) (length chunk) --- | Consume characters matching the predicate. The stops when it--- encounters a non-matching character or when it encounters a byte--- above @0x7F@. This never fails.+{- | Consume characters matching the predicate. The stops when it+encounters a non-matching character or when it encounters a byte+above @0x7F@. This never fails.+-} skipWhile :: (Char -> Bool) -> Parser e s ()-{-# inline skipWhile #-}-skipWhile p = Parser-  ( \(# arr, off0, len0 #) s0 ->-    let go off len = case len of-          0# -> (# (), off, 0# #)-          _ -> let c = indexCharArray# arr off in-            case p (C# c) of-              True -> case gtChar# c '\x7F'# of-                1# -> (# (), off, len #)-                _ -> go (off +# 1# ) (len -# 1# )-              False -> (# (), off, len #)-     in (# s0, (# | go off0 len0 #) #)-  )+{-# INLINE skipWhile #-}+skipWhile p =+  Parser+    ( \(# arr, off0, len0 #) s0 ->+        let go off len = case len of+              0# -> (# (), off, 0# #)+              _ ->+                let c = indexCharArray# arr off+                 in case p (C# c) of+                      True -> case gtChar# c '\x7F'# of+                        1# -> (# (), off, len #)+                        _ -> go (off +# 1#) (len -# 1#)+                      False -> (# (), off, len #)+         in (# s0, (# | go off0 len0 #) #)+    ) --- | Skip uppercase and lowercase letters until a non-alpha--- character is encountered.+{- | Skip uppercase and lowercase letters until a non-alpha+character is encountered.+-} skipAlpha :: Parser e s ()-{-# inline skipAlpha #-}+{-# INLINE skipAlpha #-} skipAlpha = uneffectful# $ \c ->   upcastUnitSuccess (skipAlphaAsciiLoop c) --- | Skip uppercase and lowercase letters until a non-alpha--- character is encountered.+{- | Skip uppercase and lowercase letters until a non-alpha+character is encountered.+-} skipAlpha1 :: e -> Parser e s ()-{-# inline skipAlpha1 #-}+{-# INLINE skipAlpha1 #-} skipAlpha1 e = uneffectful# $ \c ->   skipAlphaAsciiLoop1Start e c  skipAlphaAsciiLoop ::-     Bytes -- Chunk-  -> (# Int#, Int# #)-{-# inline skipAlphaAsciiLoop #-}-skipAlphaAsciiLoop !c = if length c > 0-  then-    let w = indexLatinCharArray (array c) (offset c)-     in if (w >= 'a' && w <= 'z') || (w >= 'A' && w <= 'Z')-          then skipAlphaAsciiLoop (Bytes.unsafeDrop 1 c)-          else (# unI (offset c), unI (length c) #)-  else (# unI (offset c), unI (length c) #)+  Bytes -> -- Chunk+  (# Int#, Int# #)+{-# INLINE skipAlphaAsciiLoop #-}+skipAlphaAsciiLoop !c =+  if length c > 0+    then+      let w = indexLatinCharArray (array c) (offset c)+       in if (w >= 'a' && w <= 'z') || (w >= 'A' && w <= 'Z')+            then skipAlphaAsciiLoop (Bytes.unsafeDrop 1 c)+            else (# unI (offset c), unI (length c) #)+    else (# unI (offset c), unI (length c) #)  skipAlphaAsciiLoop1Start ::-     e-  -> Bytes -- chunk-  -> Result# e ()-{-# inline skipAlphaAsciiLoop1Start #-}-skipAlphaAsciiLoop1Start e !c = if length c > 0-  then -    let w = indexLatinCharArray (array c) (offset c)-     in if (w >= 'a' && w <= 'z') || (w >= 'A' && w <= 'Z')-          then upcastUnitSuccess (skipAlphaAsciiLoop (Bytes.unsafeDrop 1 c))-          else (# e | #)-  else (# e | #)+  e ->+  Bytes -> -- chunk+  Result# e ()+{-# INLINE skipAlphaAsciiLoop1Start #-}+skipAlphaAsciiLoop1Start e !c =+  if length c > 0+    then+      let w = indexLatinCharArray (array c) (offset c)+       in if (w >= 'a' && w <= 'z') || (w >= 'A' && w <= 'Z')+            then upcastUnitSuccess (skipAlphaAsciiLoop (Bytes.unsafeDrop 1 c))+            else (# e | #)+    else (# e | #)  byteArrayToShortByteString :: PM.ByteArray -> BSS.ShortByteString-{-# inline byteArrayToShortByteString #-}+{-# INLINE byteArrayToShortByteString #-} byteArrayToShortByteString (PM.ByteArray x) = BSS.SBS x
src/Data/Bytes/Parser/Base128.hs view
@@ -1,5 +1,5 @@-{-# language BangPatterns #-}-{-# language TypeApplications #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE TypeApplications #-}  module Data.Bytes.Parser.Base128   ( -- * Unsigned@@ -9,9 +9,9 @@   ) where  import Control.Monad (when)-import Data.Bits (testBit,unsafeShiftL,(.|.),bit,clearBit)+import Data.Bits (bit, clearBit, testBit, unsafeShiftL, (.|.)) import Data.Bytes.Parser (Parser)-import Data.Word (Word8,Word16,Word32,Word64)+import Data.Word (Word16, Word32, Word64, Word8)  import qualified Data.Bytes.Parser as P 
src/Data/Bytes/Parser/BigEndian.hs view
@@ -1,20 +1,14 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UnboxedSums #-}  -- | Big-endian fixed-width numbers. module Data.Bytes.Parser.BigEndian@@ -25,12 +19,15 @@   , word64   , word128   , word256+     -- * Signed   , int8   , int16   , int32   , int64+     -- * Many+     -- ** Unsigned   , word16Array   , word32Array@@ -39,20 +36,20 @@   , word256Array   ) where -import Prelude hiding (length,any,fail,takeWhile)+import Prelude hiding (any, fail, length, takeWhile) +#if MIN_VERSION_base(4,18,0)+#else import Control.Applicative (liftA2)-import Data.Bits ((.|.),unsafeShiftL)-import Data.Bytes.Types (Bytes(..))-import Data.Bytes.Parser.Internal (Parser,uneffectful)-import Data.Bytes.Parser.Internal (Result(..))-import Data.Bytes.Parser.Internal (swapArray16,swapArray32,swapArray64,swapArray256)-import Data.Bytes.Parser.Internal (swapArray128)-import Data.Word (Word8,Word16,Word32,Word64)-import Data.Int (Int8,Int16,Int32,Int64)-import Data.Primitive (ByteArray(..),PrimArray(..))-import Data.WideWord (Word128(Word128),Word256(Word256))-import GHC.ByteOrder (ByteOrder(LittleEndian,BigEndian),targetByteOrder)+#endif+import Data.Bits (unsafeShiftL, (.|.))+import Data.Bytes.Parser.Internal (Parser, Result (..), swapArray128, swapArray16, swapArray256, swapArray32, swapArray64, uneffectful)+import Data.Bytes.Types (Bytes (..))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Primitive (ByteArray (..), PrimArray (..))+import Data.WideWord (Word128 (Word128), Word256 (Word256))+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.ByteOrder (ByteOrder (BigEndian, LittleEndian), targetByteOrder)  import qualified Data.Bytes as Bytes import qualified Data.Bytes.Parser as P@@ -62,14 +59,18 @@ word8 :: e -> Parser e s Word8 word8 = P.any --- | Parse an array of big-endian unsigned 16-bit words. If the host is--- big-endian, the implementation is optimized to simply @memcpy@ bytes--- into the result array. The result array always has elements in--- native-endian byte order.+{- | Parse an array of big-endian unsigned 16-bit words. If the host is+big-endian, the implementation is optimized to simply @memcpy@ bytes+into the result array. The result array always has elements in+native-endian byte order.+-} word16Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of big-endian 16-bit words to expect-  -> Parser e s (PrimArray Word16) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of big-endian 16-bit words to expect+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word16) word16Array e !n = case targetByteOrder of   BigEndian -> fmap (asWord16s . Bytes.toByteArrayClone) (P.take e (n * 2))   LittleEndian -> do@@ -79,9 +80,12 @@  -- | Parse an array of big-endian unsigned 32-bit words. word32Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of big-endian 32-bit words to expect-  -> Parser e s (PrimArray Word32) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of big-endian 32-bit words to expect+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word32) word32Array e !n = case targetByteOrder of   BigEndian -> fmap (asWord32s . Bytes.toByteArrayClone) (P.take e (n * 4))   LittleEndian -> do@@ -91,9 +95,12 @@  -- | Parse an array of big-endian unsigned 64-bit words. word64Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of big-endian 64-bit words to consume-  -> Parser e s (PrimArray Word64) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of big-endian 64-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word64) word64Array e !n = case targetByteOrder of   BigEndian -> fmap (asWord64s . Bytes.toByteArrayClone) (P.take e (n * 8))   LittleEndian -> do@@ -103,9 +110,12 @@  -- | Parse an array of big-endian unsigned 256-bit words. word256Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of big-endian 256-bit words to consume-  -> Parser e s (PrimArray Word256) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of big-endian 256-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word256) word256Array e !n = case targetByteOrder of   BigEndian -> fmap (asWord256s . Bytes.toByteArrayClone) (P.take e (n * 32))   LittleEndian -> do@@ -115,9 +125,12 @@  -- | Parse an array of big-endian unsigned 128-bit words. word128Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of big-endian 128-bit words to consume-  -> Parser e s (PrimArray Word128) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of big-endian 128-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word128) word128Array e !n = case targetByteOrder of   BigEndian -> fmap (asWord128s . Bytes.toByteArrayClone) (P.take e (n * 16))   LittleEndian -> do@@ -142,58 +155,64 @@  -- | Unsigned 16-bit word. word16 :: e -> Parser e s Word16-word16 e = uneffectful $ \chunk -> if length chunk >= 2-  then-    let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8-        wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-     in Success-          (fromIntegral @Word @Word16 (unsafeShiftL (fromIntegral wa) 8 .|. fromIntegral wb))-          (offset chunk + 2) (length chunk - 2)-  else Failure e+word16 e = uneffectful $ \chunk ->+  if length chunk >= 2+    then+      let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8+          wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8+       in Success+            (fromIntegral @Word @Word16 (unsafeShiftL (fromIntegral wa) 8 .|. fromIntegral wb))+            (offset chunk + 2)+            (length chunk - 2)+    else Failure e  -- | Unsigned 32-bit word. word32 :: e -> Parser e s Word32-word32 e = uneffectful $ \chunk -> if length chunk >= 4-  then-    let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8-        wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-        wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8-        wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8-     in Success-          (fromIntegral @Word @Word32-            ( unsafeShiftL (fromIntegral wa) 24 .|.-              unsafeShiftL (fromIntegral wb) 16 .|.-              unsafeShiftL (fromIntegral wc) 8 .|.-              fromIntegral wd+word32 e = uneffectful $ \chunk ->+  if length chunk >= 4+    then+      let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8+          wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8+          wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8+          wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8+       in Success+            ( fromIntegral @Word @Word32+                ( unsafeShiftL (fromIntegral wa) 24+                    .|. unsafeShiftL (fromIntegral wb) 16+                    .|. unsafeShiftL (fromIntegral wc) 8+                    .|. fromIntegral wd+                )             )-          )-          (offset chunk + 4) (length chunk - 4)-  else Failure e+            (offset chunk + 4)+            (length chunk - 4)+    else Failure e  -- | Unsigned 64-bit word. word64 :: e -> Parser e s Word64-word64 e = uneffectful $ \chunk -> if length chunk >= 8-  then-    let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8-        wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-        wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8-        wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8-        we = PM.indexByteArray (array chunk) (offset chunk + 4) :: Word8-        wf = PM.indexByteArray (array chunk) (offset chunk + 5) :: Word8-        wg = PM.indexByteArray (array chunk) (offset chunk + 6) :: Word8-        wh = PM.indexByteArray (array chunk) (offset chunk + 7) :: Word8-     in Success-          ( unsafeShiftL (fromIntegral wa) 56 .|.-            unsafeShiftL (fromIntegral wb) 48 .|.-            unsafeShiftL (fromIntegral wc) 40 .|.-            unsafeShiftL (fromIntegral wd) 32 .|.-            unsafeShiftL (fromIntegral we) 24 .|.-            unsafeShiftL (fromIntegral wf) 16 .|.-            unsafeShiftL (fromIntegral wg) 8 .|.-            fromIntegral wh-          )-          (offset chunk + 8) (length chunk - 8)-  else Failure e+word64 e = uneffectful $ \chunk ->+  if length chunk >= 8+    then+      let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8+          wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8+          wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8+          wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8+          we = PM.indexByteArray (array chunk) (offset chunk + 4) :: Word8+          wf = PM.indexByteArray (array chunk) (offset chunk + 5) :: Word8+          wg = PM.indexByteArray (array chunk) (offset chunk + 6) :: Word8+          wh = PM.indexByteArray (array chunk) (offset chunk + 7) :: Word8+       in Success+            ( unsafeShiftL (fromIntegral wa) 56+                .|. unsafeShiftL (fromIntegral wb) 48+                .|. unsafeShiftL (fromIntegral wc) 40+                .|. unsafeShiftL (fromIntegral wd) 32+                .|. unsafeShiftL (fromIntegral we) 24+                .|. unsafeShiftL (fromIntegral wf) 16+                .|. unsafeShiftL (fromIntegral wg) 8+                .|. fromIntegral wh+            )+            (offset chunk + 8)+            (length chunk - 8)+    else Failure e  -- | Unsigned 128-bit word. word128 :: e -> Parser e s Word128
src/Data/Bytes/Parser/Internal.hs view
@@ -1,26 +1,19 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language NamedFieldPuns #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UnboxedTuples #-}  module Data.Bytes.Parser.Internal-  ( Parser(..)-  , Result(..)-  , InternalStep(..)+  ( Parser (..)+  , Result (..)+  , InternalStep (..)   , Bytes#   , ST#   , Result#@@ -34,7 +27,7 @@   , fail   , indexLatinCharArray   , upcastUnitSuccess-    -- Swapping+  -- Swapping   , swapArray16   , swapArray32   , swapArray64@@ -42,15 +35,15 @@   , swapArray256   ) where -import Prelude hiding (length,any,fail,takeWhile)+import Prelude hiding (any, fail, length, takeWhile)  import Control.Applicative (Alternative)-import Control.Monad.ST.Run (runByteArrayST)-import Data.Primitive (ByteArray(ByteArray))-import Data.Bytes.Types (Bytes(..))+import Control.Monad.ST (runST)+import Data.Bytes.Types (Bytes (..)) import Data.Kind (Type)+import Data.Primitive (ByteArray (ByteArray)) import Data.Word (Word8)-import GHC.Exts (TYPE,RuntimeRep,Int(I#),Int#,State#,ByteArray#,Char(C#))+import GHC.Exts (ByteArray#, Char (C#), Int (I#), Int#, RuntimeRep, State#, TYPE)  import qualified Control.Applicative import qualified Control.Monad@@ -59,71 +52,81 @@  -- | A non-resumable parser. newtype Parser :: forall (r :: RuntimeRep). Type -> Type -> TYPE r -> Type where-  Parser :: forall (r :: RuntimeRep) (e :: Type) (s :: Type) (a :: TYPE r).-    { runParser :: (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a) } -> Parser e s a+  Parser ::+    forall (r :: RuntimeRep) (e :: Type) (s :: Type) (a :: TYPE r).+    {runParser :: (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)} ->+    Parser e s a  -- The result of running a parser. Used internally. data Result e a   = Failure e-    -- An error message indicating what went wrong.-  | Success !a !Int !Int-    -- The parsed value, the offset after the last consumed byte, and the-    -- number of bytes remaining in parsed slice.+  | -- An error message indicating what went wrong.+    Success !a !Int !Int +-- The parsed value, the offset after the last consumed byte, and the+-- number of bytes remaining in parsed slice.+ data InternalStep a = InternalStep !a !Int !Int  uneffectful :: (Bytes -> Result e a) -> Parser e s a-{-# inline uneffectful #-}-uneffectful f = Parser-  ( \b s0 -> (# s0, unboxResult (f (boxBytes b)) #) )+{-# INLINE uneffectful #-}+uneffectful f =+  Parser+    (\b s0 -> (# s0, unboxResult (f (boxBytes b)) #))  -- This is like uneffectful but for parsers that always succeed. -- These combinators typically have names that begin with @try@. unfailing :: (Bytes -> InternalStep a) -> Parser e s a-{-# inline unfailing #-}-unfailing f = Parser-  ( \b s0 -> (# s0, case f (boxBytes b) of { InternalStep a (I# off) (I# len) -> (# | (# a, off, len #) #) } #) )+{-# INLINE unfailing #-}+unfailing f =+  Parser+    (\b s0 -> (# s0, case f (boxBytes b) of InternalStep a (I# off) (I# len) -> (# | (# a, off, len #) #) #))  boxBytes :: Bytes# -> Bytes-{-# inline boxBytes #-}+{-# INLINE boxBytes #-} boxBytes (# a, b, c #) = Bytes (ByteArray a) (I# b) (I# c)  unboxBytes :: Bytes -> Bytes#-{-# inline unboxBytes #-}-unboxBytes (Bytes (ByteArray a) (I# b) (I# c)) = (# a,b,c #)+{-# INLINE unboxBytes #-}+unboxBytes (Bytes (ByteArray a) (I# b) (I# c)) = (# a, b, c #)  type Bytes# = (# ByteArray#, Int#, Int# #) type ST# s (a :: TYPE r) = State# s -> (# State# s, a #) type Result# e (a :: TYPE r) =-  (# e-  | (# a, Int#, Int# #) #) -- ints are offset and length+  (#+    e |+    (# a, Int#, Int# #) -- ints are offset and length+  #)  unboxResult :: Result e a -> Result# e a-{-# inline unboxResult #-}+{-# INLINE unboxResult #-} unboxResult (Success a (I# b) (I# c)) = (# | (# a, b, c #) #) unboxResult (Failure e) = (# e | #) --- | Combines the error messages using '<>' when both--- parsers fail.-instance Monoid e => Alternative (Parser e s) where-  {-# inline empty #-}-  {-# inline (<|>) #-}+{- | Combines the error messages using '<>' when both+parsers fail.+-}+instance (Monoid e) => Alternative (Parser e s) where+  {-# INLINE empty #-}+  {-# INLINE (<|>) #-}   empty = fail mempty-  Parser f <|> Parser g = Parser-    (\x s0 -> case f x s0 of-      (# s1, r0 #) -> case r0 of-        (# eRight | #) -> case g x s1 of-          (# s2, r1 #) -> case r1 of-            (# eLeft | #) -> (# s2, (# eRight <> eLeft | #) #)-            (# | r #) -> (# s2, (# | r #) #)-        (# | r #) -> (# s1, (# | r #) #)-    )+  Parser f <|> Parser g =+    Parser+      ( \x s0 -> case f x s0 of+          (# s1, r0 #) -> case r0 of+            (# eRight | #) -> case g x s1 of+              (# s2, r1 #) -> case r1 of+                (# eLeft | #) -> (# s2, (# eRight <> eLeft | #) #)+                (# | r #) -> (# s2, (# | r #) #)+            (# | r #) -> (# s1, (# | r #) #)+      )  -- | Fail with the provided error message. fail ::-     e -- ^ Error message-  -> Parser e s a-{-# inline fail #-}+  -- | Error message+  e ->+  Parser e s a+{-# INLINE fail #-} fail e = uneffectful $ \_ -> Failure e  instance Applicative (Parser e s) where@@ -131,165 +134,175 @@   (<*>) = Control.Monad.ap  instance Monad (Parser e s) where-  {-# inline (>>=) #-}+  {-# INLINE (>>=) #-}   (>>=) = bindParser  instance Functor (Parser e s) where-  {-# inline fmap #-}-  fmap f (Parser g) = Parser-    (\x s0 -> case g x s0 of-      (# s1, r #) -> case r of-        (# e | #) -> (# s1, (# e | #) #)-        (# | (# a, b, c #) #) -> (# s1, (# | (# f a, b, c #) #) #)-    )+  {-# INLINE fmap #-}+  fmap f (Parser g) =+    Parser+      ( \x s0 -> case g x s0 of+          (# s1, r #) -> case r of+            (# e | #) -> (# s1, (# e | #) #)+            (# | (# a, b, c #) #) -> (# s1, (# | (# f a, b, c #) #) #)+      )  indexLatinCharArray :: ByteArray -> Int -> Char-{-# inline indexLatinCharArray #-}+{-# INLINE indexLatinCharArray #-} indexLatinCharArray (ByteArray arr) (I# off) =   C# (Exts.indexCharArray# arr off)  uneffectful# :: (Bytes -> Result# e a) -> Parser e s a-{-# inline uneffectful# #-}-uneffectful# f = Parser-  ( \b s0 -> (# s0, (f (boxBytes b)) #) )+{-# INLINE uneffectful# #-}+uneffectful# f =+  Parser+    (\b s0 -> (# s0, (f (boxBytes b)) #)) -uneffectfulInt# :: (Bytes -> Result# e Int# ) -> Parser e s Int#-{-# inline uneffectfulInt# #-}-uneffectfulInt# f = Parser-  ( \b s0 -> (# s0, (f (boxBytes b)) #) )+uneffectfulInt# :: (Bytes -> Result# e Int#) -> Parser e s Int#+{-# INLINE uneffectfulInt# #-}+uneffectfulInt# f =+  Parser+    (\b s0 -> (# s0, (f (boxBytes b)) #))  upcastUnitSuccess :: (# Int#, Int# #) -> Result# e ()-{-# inline upcastUnitSuccess #-}+{-# INLINE upcastUnitSuccess #-} upcastUnitSuccess (# b, c #) = (# | (# (), b, c #) #)  swapArray16 :: Bytes -> ByteArray-swapArray16 (Bytes{array,offset,length}) = runByteArrayST $ do+swapArray16 (Bytes {array, offset, length}) = runST $ do   dst <- PM.newByteArray length-  let go !ixSrc !ixDst !len = if len > 0-        then do-          let v0 = PM.indexByteArray array ixSrc :: Word8-              v1 = PM.indexByteArray array (ixSrc + 1) :: Word8-          PM.writeByteArray dst ixDst v1-          PM.writeByteArray dst (ixDst + 1) v0-          go (ixSrc + 2) (ixDst + 2) (len - 2)-        else pure ()+  let go !ixSrc !ixDst !len =+        if len > 0+          then do+            let v0 = PM.indexByteArray array ixSrc :: Word8+                v1 = PM.indexByteArray array (ixSrc + 1) :: Word8+            PM.writeByteArray dst ixDst v1+            PM.writeByteArray dst (ixDst + 1) v0+            go (ixSrc + 2) (ixDst + 2) (len - 2)+          else pure ()   go offset 0 length   PM.unsafeFreezeByteArray dst  swapArray32 :: Bytes -> ByteArray-swapArray32 (Bytes{array,offset,length}) = runByteArrayST $ do+swapArray32 (Bytes {array, offset, length}) = runST $ do   dst <- PM.newByteArray length-  let go !ixSrc !ixDst !len = if len > 0-        then do-          let v0 = PM.indexByteArray array ixSrc :: Word8-              v1 = PM.indexByteArray array (ixSrc + 1) :: Word8-              v2 = PM.indexByteArray array (ixSrc + 2) :: Word8-              v3 = PM.indexByteArray array (ixSrc + 3) :: Word8-          PM.writeByteArray dst ixDst v3-          PM.writeByteArray dst (ixDst + 1) v2-          PM.writeByteArray dst (ixDst + 2) v1-          PM.writeByteArray dst (ixDst + 3) v0-          go (ixSrc + 4) (ixDst + 4) (len - 4)-        else pure ()+  let go !ixSrc !ixDst !len =+        if len > 0+          then do+            let v0 = PM.indexByteArray array ixSrc :: Word8+                v1 = PM.indexByteArray array (ixSrc + 1) :: Word8+                v2 = PM.indexByteArray array (ixSrc + 2) :: Word8+                v3 = PM.indexByteArray array (ixSrc + 3) :: Word8+            PM.writeByteArray dst ixDst v3+            PM.writeByteArray dst (ixDst + 1) v2+            PM.writeByteArray dst (ixDst + 2) v1+            PM.writeByteArray dst (ixDst + 3) v0+            go (ixSrc + 4) (ixDst + 4) (len - 4)+          else pure ()   go offset 0 length   PM.unsafeFreezeByteArray dst  swapArray64 :: Bytes -> ByteArray-swapArray64 (Bytes{array,offset,length}) = runByteArrayST $ do+swapArray64 (Bytes {array, offset, length}) = runST $ do   dst <- PM.newByteArray length-  let go !ixSrc !ixDst !len = if len > 0-        then do-          let v0 = PM.indexByteArray array ixSrc :: Word8-              v1 = PM.indexByteArray array (ixSrc + 1) :: Word8-              v2 = PM.indexByteArray array (ixSrc + 2) :: Word8-              v3 = PM.indexByteArray array (ixSrc + 3) :: Word8-              v4 = PM.indexByteArray array (ixSrc + 4) :: Word8-              v5 = PM.indexByteArray array (ixSrc + 5) :: Word8-              v6 = PM.indexByteArray array (ixSrc + 6) :: Word8-              v7 = PM.indexByteArray array (ixSrc + 7) :: Word8-          PM.writeByteArray dst ixDst v7-          PM.writeByteArray dst (ixDst + 1) v6-          PM.writeByteArray dst (ixDst + 2) v5-          PM.writeByteArray dst (ixDst + 3) v4-          PM.writeByteArray dst (ixDst + 4) v3-          PM.writeByteArray dst (ixDst + 5) v2-          PM.writeByteArray dst (ixDst + 6) v1-          PM.writeByteArray dst (ixDst + 7) v0-          go (ixSrc + 8) (ixDst + 8) (len - 8)-        else pure ()+  let go !ixSrc !ixDst !len =+        if len > 0+          then do+            let v0 = PM.indexByteArray array ixSrc :: Word8+                v1 = PM.indexByteArray array (ixSrc + 1) :: Word8+                v2 = PM.indexByteArray array (ixSrc + 2) :: Word8+                v3 = PM.indexByteArray array (ixSrc + 3) :: Word8+                v4 = PM.indexByteArray array (ixSrc + 4) :: Word8+                v5 = PM.indexByteArray array (ixSrc + 5) :: Word8+                v6 = PM.indexByteArray array (ixSrc + 6) :: Word8+                v7 = PM.indexByteArray array (ixSrc + 7) :: Word8+            PM.writeByteArray dst ixDst v7+            PM.writeByteArray dst (ixDst + 1) v6+            PM.writeByteArray dst (ixDst + 2) v5+            PM.writeByteArray dst (ixDst + 3) v4+            PM.writeByteArray dst (ixDst + 4) v3+            PM.writeByteArray dst (ixDst + 5) v2+            PM.writeByteArray dst (ixDst + 6) v1+            PM.writeByteArray dst (ixDst + 7) v0+            go (ixSrc + 8) (ixDst + 8) (len - 8)+          else pure ()   go offset 0 length   PM.unsafeFreezeByteArray dst  swapArray128 :: Bytes -> ByteArray-swapArray128 (Bytes{array,offset,length}) = runByteArrayST $ do+swapArray128 (Bytes {array, offset, length}) = runST $ do   dst <- PM.newByteArray length-  let go !ixSrc !ixDst !len = if len > 0-        then do-          let v0 = PM.indexByteArray array ixSrc :: Word8-              v1 = PM.indexByteArray array (ixSrc + 1) :: Word8-              v2 = PM.indexByteArray array (ixSrc + 2) :: Word8-              v3 = PM.indexByteArray array (ixSrc + 3) :: Word8-              v4 = PM.indexByteArray array (ixSrc + 4) :: Word8-              v5 = PM.indexByteArray array (ixSrc + 5) :: Word8-              v6 = PM.indexByteArray array (ixSrc + 6) :: Word8-              v7 = PM.indexByteArray array (ixSrc + 7) :: Word8-              v8 = PM.indexByteArray array (ixSrc + 8) :: Word8-              v9 = PM.indexByteArray array (ixSrc + 9) :: Word8-              v10 = PM.indexByteArray array (ixSrc + 10) :: Word8-              v11 = PM.indexByteArray array (ixSrc + 11) :: Word8-              v12 = PM.indexByteArray array (ixSrc + 12) :: Word8-              v13 = PM.indexByteArray array (ixSrc + 13) :: Word8-              v14 = PM.indexByteArray array (ixSrc + 14) :: Word8-              v15 = PM.indexByteArray array (ixSrc + 15) :: Word8-          PM.writeByteArray dst ixDst v15-          PM.writeByteArray dst (ixDst + 1) v14-          PM.writeByteArray dst (ixDst + 2) v13-          PM.writeByteArray dst (ixDst + 3) v12-          PM.writeByteArray dst (ixDst + 4) v11-          PM.writeByteArray dst (ixDst + 5) v10-          PM.writeByteArray dst (ixDst + 6) v9-          PM.writeByteArray dst (ixDst + 7) v8-          PM.writeByteArray dst (ixDst + 8) v7-          PM.writeByteArray dst (ixDst + 9) v6-          PM.writeByteArray dst (ixDst + 10) v5-          PM.writeByteArray dst (ixDst + 11) v4-          PM.writeByteArray dst (ixDst + 12) v3-          PM.writeByteArray dst (ixDst + 13) v2-          PM.writeByteArray dst (ixDst + 14) v1-          PM.writeByteArray dst (ixDst + 15) v0-          go (ixSrc + 16) (ixDst + 16) (len - 16)-        else pure ()+  let go !ixSrc !ixDst !len =+        if len > 0+          then do+            let v0 = PM.indexByteArray array ixSrc :: Word8+                v1 = PM.indexByteArray array (ixSrc + 1) :: Word8+                v2 = PM.indexByteArray array (ixSrc + 2) :: Word8+                v3 = PM.indexByteArray array (ixSrc + 3) :: Word8+                v4 = PM.indexByteArray array (ixSrc + 4) :: Word8+                v5 = PM.indexByteArray array (ixSrc + 5) :: Word8+                v6 = PM.indexByteArray array (ixSrc + 6) :: Word8+                v7 = PM.indexByteArray array (ixSrc + 7) :: Word8+                v8 = PM.indexByteArray array (ixSrc + 8) :: Word8+                v9 = PM.indexByteArray array (ixSrc + 9) :: Word8+                v10 = PM.indexByteArray array (ixSrc + 10) :: Word8+                v11 = PM.indexByteArray array (ixSrc + 11) :: Word8+                v12 = PM.indexByteArray array (ixSrc + 12) :: Word8+                v13 = PM.indexByteArray array (ixSrc + 13) :: Word8+                v14 = PM.indexByteArray array (ixSrc + 14) :: Word8+                v15 = PM.indexByteArray array (ixSrc + 15) :: Word8+            PM.writeByteArray dst ixDst v15+            PM.writeByteArray dst (ixDst + 1) v14+            PM.writeByteArray dst (ixDst + 2) v13+            PM.writeByteArray dst (ixDst + 3) v12+            PM.writeByteArray dst (ixDst + 4) v11+            PM.writeByteArray dst (ixDst + 5) v10+            PM.writeByteArray dst (ixDst + 6) v9+            PM.writeByteArray dst (ixDst + 7) v8+            PM.writeByteArray dst (ixDst + 8) v7+            PM.writeByteArray dst (ixDst + 9) v6+            PM.writeByteArray dst (ixDst + 10) v5+            PM.writeByteArray dst (ixDst + 11) v4+            PM.writeByteArray dst (ixDst + 12) v3+            PM.writeByteArray dst (ixDst + 13) v2+            PM.writeByteArray dst (ixDst + 14) v1+            PM.writeByteArray dst (ixDst + 15) v0+            go (ixSrc + 16) (ixDst + 16) (len - 16)+          else pure ()   go offset 0 length   PM.unsafeFreezeByteArray dst  swapArray256 :: Bytes -> ByteArray-swapArray256 (Bytes{array,offset,length}) = runByteArrayST $ do+swapArray256 (Bytes {array, offset, length}) = runST $ do   dst <- PM.newByteArray length-  let go !ixSrc !ixDst !len = if len > 0-        then do-          let loop !i-                | i < 32 = do-                    let v = PM.indexByteArray array (ixSrc + i) :: Word8-                    PM.writeByteArray dst (ixDst + (31 - i)) v-                    loop (i + 1)-                | otherwise = pure ()-          loop 0-          go (ixSrc + 32) (ixDst + 32) (len - 32)-        else pure ()+  let go !ixSrc !ixDst !len =+        if len > 0+          then do+            let loop !i+                  | i < 32 = do+                      let v = PM.indexByteArray array (ixSrc + i) :: Word8+                      PM.writeByteArray dst (ixDst + (31 - i)) v+                      loop (i + 1)+                  | otherwise = pure ()+            loop 0+            go (ixSrc + 32) (ixDst + 32) (len - 32)+          else pure ()   go offset 0 length   PM.unsafeFreezeByteArray dst  pureParser :: a -> Parser e s a-{-# inline pureParser #-}-pureParser a = Parser-  (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))+{-# INLINE pureParser #-}+pureParser a =+  Parser+    (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))  bindParser :: Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindParser #-}-bindParser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindParser #-}+bindParser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )
src/Data/Bytes/Parser/Latin.hs view
@@ -1,1302 +1,1524 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}-{-# language CPP #-}---- | Parse input as though it were text encoded by--- ISO 8859-1 (Latin-1). All byte sequences are valid--- text under ISO 8859-1.-module Data.Bytes.Parser.Latin-  ( -- * Matching-    -- ** Required-    char-  , char2-  , char3-  , char4-  , char5-  , char6-  , char7-  , char8-  , char9-  , char10-  , char11-  , char12-    -- ** Try-  , trySatisfy-  , trySatisfyThen-    -- * One Character-  , any-  , opt-  , opt#-    -- * Many Characters-  , takeTrailedBy-    -- * Lookahead-  , peek-  , peek'-    -- * Skip-  , skipDigits-  , skipDigits1-  , skipChar-  , skipChar1-  , skipTrailedBy-  , skipUntil-  , skipWhile-    -- * End of Input-  , endOfInput-  , isEndOfInput-    -- * Numbers-    -- ** Decimal-    -- *** Unsigned-  , decWord-  , decWord8-  , decWord16-  , decWord32-  , decWord64-    -- *** Signed-  , decUnsignedInt-  , decUnsignedInt#-  , decSignedInt-  , decStandardInt-  , decTrailingInt-  , decTrailingInt#-  , decSignedInteger-  , decUnsignedInteger-  , decTrailingInteger-    -- ** Hexadecimal-    -- *** Variable Length-  , hexWord8-  , hexWord16-  , hexWord32-    -- *** Fixed Length-  , hexFixedWord8-  , hexFixedWord16-  , hexFixedWord32-  , hexFixedWord64-  , hexFixedWord128-  , hexFixedWord256-    -- *** Digit-  , hexNibbleLower-  , tryHexNibbleLower-  , hexNibble-  , tryHexNibble-  ) where--import Prelude hiding (length,any,fail,takeWhile)--import Data.Bits ((.|.))-import Data.Bytes.Types (Bytes(..))-import Data.Bytes.Parser.Internal (InternalStep(..),unfailing)-import Data.Bytes.Parser (bindFromLiftedToInt,isEndOfInput,endOfInput)-import Data.Bytes.Parser.Internal (Parser(..),ST#,uneffectful,Result#,uneffectful#)-import Data.Bytes.Parser.Internal (Result(..),indexLatinCharArray,upcastUnitSuccess)-import Data.Bytes.Parser.Internal (boxBytes)-import Data.Bytes.Parser.Unsafe (expose,cursor,unconsume)-import Data.Char (ord)-import Data.Kind (Type)-import Data.WideWord (Word256(Word256),Word128(Word128))-import Data.Word (Word8)-import GHC.Exts (Int(I#),Char(C#),Word#,Int#,Char#,(+#),(-#),indexCharArray#)-import GHC.Exts (TYPE,RuntimeRep,int2Word#,or#)-import GHC.Exts (ltWord#,gtWord#,notI#)-import GHC.Word (Word(W#),Word8(W8#),Word16(W16#),Word32(W32#),Word64(W64#))--import qualified GHC.Exts as Exts-import qualified Data.Bytes as Bytes-import qualified Data.Primitive as PM---- | Runs the predicate on the next character in the input. If the--- predicate is matched, this consumes the character. Otherwise,--- the character is not consumed. This returns @False@ if the end--- of the input has been reached. This never fails.-trySatisfy :: (Char -> Bool) -> Parser e s Bool-trySatisfy f = uneffectful $ \chunk -> case length chunk of-  0 -> Success False (offset chunk) (length chunk)-  _ -> case f (indexLatinCharArray (array chunk) (offset chunk)) of-    True -> Success True (offset chunk + 1) (length chunk - 1)-    False -> Success False (offset chunk) (length chunk)---- | Runs the function on the next character in the input. If the--- function returns @Just@, this consumes the character and then--- runs the parser on the remaining input. If the function returns--- @Nothing@, this does not consume the tested character, and it--- runs the default parser on the input (which includes the tested--- character). If there is no input remaining, this also runs the--- default parser. This combinator never fails.-trySatisfyThen :: forall (r :: RuntimeRep) (e :: Type) (s :: Type) (a :: TYPE r).-     Parser e s a -- ^ Default parser. Runs on @Nothing@ or end of input.-  -> (Char -> Maybe (Parser e s a)) -- ^ Parser-selecting predicate-  -> Parser e s a-{-# inline trySatisfyThen #-}-trySatisfyThen (Parser g) f = Parser-  (\input@(# arr,off0,len0 #) s0 -> case len0 of-    0# -> g input s0-    _ -> case f (C# (indexCharArray# arr off0)) of-      Nothing -> g input s0-      Just (Parser p) -> p (# arr, off0 +# 1#, len0 -# 1# #) s0-  )---- | Consume the next character, failing if it does not--- match the expected value or if there is no more input.-char :: e -> Char -> Parser e s ()-{-# inline char #-}-char e !c = uneffectful $ \chunk -> if length chunk > 0-  then if indexLatinCharArray (array chunk) (offset chunk) == c-    then Success () (offset chunk + 1) (length chunk - 1)-    else Failure e-  else Failure e---- | Consume the next two characters, failing if they do--- not match the expected values.------ > char2 e a b === char e a *> char e b-char2 :: e -> Char -> Char -> Parser e s ()-{-# inline char2 #-}-char2 e !c0 !c1 = uneffectful $ \chunk ->-  if | length chunk > 1-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-         -> Success () (offset chunk + 2) (length chunk - 2)-     | otherwise -> Failure e---- | Consume three characters, failing if they do--- not match the expected values.------ > char3 e a b c === char e a *> char e b *> char e c-char3 :: e -> Char -> Char -> Char -> Parser e s ()-{-# inline char3 #-}-char3 e !c0 !c1 !c2 = uneffectful $ \chunk ->-  if | length chunk > 2-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-         -> Success () (offset chunk + 3) (length chunk - 3)-     | otherwise -> Failure e---- | Consume four characters, failing if they do--- not match the expected values.------ > char4 e a b c d === char e a *> char e b *> char e c *> char e d-char4 :: e -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char4 #-}-char4 e !c0 !c1 !c2 !c3 = uneffectful $ \chunk ->-  if | length chunk > 3-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-         -> Success () (offset chunk + 4) (length chunk - 4)-     | otherwise -> Failure e---- | Consume five characters, failing if they do--- not match the expected values.-char5 :: e -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char5 #-}-char5 e !c0 !c1 !c2 !c3 !c4 = uneffectful $ \chunk ->-  if | length chunk > 4-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-         -> Success () (offset chunk + 5) (length chunk - 5)-     | otherwise -> Failure e---- | Consume six characters, failing if they do--- not match the expected values.-char6 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char6 #-}-char6 e !c0 !c1 !c2 !c3 !c4 !c5 = uneffectful $ \chunk ->-  if | length chunk > 5-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-         -> Success () (offset chunk + 6) (length chunk - 6)-     | otherwise -> Failure e---- | Consume seven characters, failing if they do--- not match the expected values.-char7 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char7 #-}-char7 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 = uneffectful $ \chunk ->-  if | length chunk > 6-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-     , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-         -> Success () (offset chunk + 7) (length chunk - 7)-     | otherwise -> Failure e---- | Consume eight characters, failing if they do--- not match the expected values.-char8 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char8 #-}-char8 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 = uneffectful $ \chunk ->-  if | length chunk > 7-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-     , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-     , indexLatinCharArray (array chunk) (offset chunk + 7) == c7-         -> Success () (offset chunk + 8) (length chunk - 8)-     | otherwise -> Failure e---- | Consume nine characters, failing if they do--- not match the expected values.-char9 :: e -> Char -> Char -> Char -> Char-  -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char9 #-}-char9 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 = uneffectful $ \chunk ->-  if | length chunk > 8-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-     , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-     , indexLatinCharArray (array chunk) (offset chunk + 7) == c7-     , indexLatinCharArray (array chunk) (offset chunk + 8) == c8-         -> Success () (offset chunk + 9) (length chunk - 9)-     | otherwise -> Failure e---- | Consume ten characters, failing if they do--- not match the expected values.-char10 :: e -> Char -> Char -> Char -> Char -> Char-  -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char10 #-}-char10 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 = uneffectful $ \chunk ->-  if | length chunk > 9-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-     , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-     , indexLatinCharArray (array chunk) (offset chunk + 7) == c7-     , indexLatinCharArray (array chunk) (offset chunk + 8) == c8-     , indexLatinCharArray (array chunk) (offset chunk + 9) == c9-         -> Success () (offset chunk + 10) (length chunk - 10)-     | otherwise -> Failure e---- | Consume eleven characters, failing if they do--- not match the expected values.-char11 :: e -> Char -> Char -> Char -> Char -> Char -> Char-  -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char11 #-}-char11 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 !c10 = uneffectful $ \chunk ->-  if | length chunk > 10-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-     , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-     , indexLatinCharArray (array chunk) (offset chunk + 7) == c7-     , indexLatinCharArray (array chunk) (offset chunk + 8) == c8-     , indexLatinCharArray (array chunk) (offset chunk + 9) == c9-     , indexLatinCharArray (array chunk) (offset chunk + 10) == c10-         -> Success () (offset chunk + 11) (length chunk - 11)-     | otherwise -> Failure e---- | Consume twelve characters, failing if they do--- not match the expected values.-char12 :: e -> Char -> Char -> Char -> Char -> Char -> Char-  -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()-{-# inline char12 #-}-char12 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 !c10 !c11 = uneffectful $ \chunk ->-  if | length chunk > 11-     , indexLatinCharArray (array chunk) (offset chunk) == c0-     , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-     , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-     , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-     , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-     , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-     , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-     , indexLatinCharArray (array chunk) (offset chunk + 7) == c7-     , indexLatinCharArray (array chunk) (offset chunk + 8) == c8-     , indexLatinCharArray (array chunk) (offset chunk + 9) == c9-     , indexLatinCharArray (array chunk) (offset chunk + 10) == c10-     , indexLatinCharArray (array chunk) (offset chunk + 11) == c11-         -> Success () (offset chunk + 12) (length chunk - 12)-     | otherwise -> Failure e---- | Consumes and returns the next character in the input.-any :: e -> Parser e s Char-{-# inline any #-}-any e = uneffectful $ \chunk -> if length chunk > 0-  then-    let c = indexLatinCharArray (array chunk) (offset chunk)-     in Success c (offset chunk + 1) (length chunk - 1)-  else Failure e---- | Consume a character from the input or return @Nothing@ if--- end of the stream has been reached. Since ISO 8859-1 maps every--- bytes to a character, this parser never fails.-opt :: Parser e s (Maybe Char)-{-# inline opt #-}-opt = uneffectful $ \chunk -> case length chunk of-  0 -> Success Nothing (offset chunk) (length chunk)-  _ -> Success-    (Just (indexLatinCharArray (array chunk) (offset chunk)))-    (offset chunk + 1) (length chunk - 1)---- | Variant of @opt@ with unboxed result.-opt# :: Parser e s (# (# #) | Char# #)-{-# inline opt# #-}-opt# = Parser-  (\(# arr, off, len #) s0 -> case len of-    0# -> (# s0, (# | (# (# (# #) | #), off, len #) #) #)-    _ -> (# s0, (# | (# (# | indexCharArray# arr off #), off +# 1#, len -# 1# #) #) #)-  )--skipDigitsAsciiLoop ::-     Bytes -- Chunk-  -> (# Int#, Int# #)-skipDigitsAsciiLoop !c = if length c > 0-  then-    let w = indexLatinCharArray (array c) (offset c)-     in if w >= '0' && w <= '9'-          then skipDigitsAsciiLoop (Bytes.unsafeDrop 1 c)-          else (# unI (offset c), unI (length c) #)-  else (# unI (offset c), unI (length c) #)--skipDigitsAscii1LoopStart ::-     e-  -> Bytes -- chunk-  -> Result# e ()-skipDigitsAscii1LoopStart e !c = if length c > 0-  then-    let w = indexLatinCharArray (array c) (offset c)-     in if w >= '0' && w <= '9'-          then upcastUnitSuccess (skipDigitsAsciiLoop (Bytes.unsafeDrop 1 c))-          else (# e | #)-  else (# e | #)---- | Variant of 'skipDigits' that requires at least one digit--- to be present.-skipDigits1 :: e -> Parser e s ()-{-# inline skipDigits1 #-}-skipDigits1 e = uneffectful# $ \c ->-  skipDigitsAscii1LoopStart e c---- | Skip the characters @0-9@ until a non-digit is encountered.--- This parser does not fail.-skipDigits :: Parser e s ()-skipDigits = uneffectful# $ \c ->-  upcastUnitSuccess (skipDigitsAsciiLoop c)--unI :: Int -> Int#-{-# inline unI #-}-unI (I# w) = w---- | Skip the character any number of times. This succeeds--- even if the character was not present.-skipChar :: Char -> Parser e s ()-{-# inline skipChar #-}-skipChar !w = uneffectful# $ \c ->-  upcastUnitSuccess (skipLoop w c)---- | Skip the character any number of times. It must occur--- at least once or else this will fail.-skipChar1 :: e -> Char -> Parser e s ()-{-# inline skipChar1 #-}-skipChar1 e !w = uneffectful# $ \c ->-  skipLoop1Start e w c--skipLoop ::-     Char -- byte to match-  -> Bytes -- Chunk-  -> (# Int#, Int# #)-skipLoop !w !c = if length c > 0-  then if indexLatinCharArray (array c) (offset c) == w-    then skipLoop w (Bytes.unsafeDrop 1 c)-    else (# unI (offset c), unI (length c) #)-  else (# unI (offset c), unI (length c) #)--skipLoop1Start ::-     e-  -> Char -- byte to match-  -> Bytes -- chunk-  -> Result# e ()-skipLoop1Start e !w !chunk0 = if length chunk0 > 0-  then if indexLatinCharArray (array chunk0) (offset chunk0) == w-    then upcastUnitSuccess (skipLoop w (Bytes.unsafeDrop 1 chunk0))-    else (# e | #)-  else (# e | #)---- | Parse a decimal-encoded 8-bit word. If the number is larger--- than 255, this parser fails.-decWord8 :: e -> Parser e s Word8-decWord8 e = Parser-  (\chunk0 s0 -> case decSmallWordStart e 256 (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord8Result r #)-  )---- | Parse a hexadecimal-encoded 8-bit word. If the number is larger--- than 255, this parser fails. This allows leading zeroes and is--- insensitive to case. For example, @00A@, @0a@ and @A@ would all--- be accepted as the same number.-hexWord8 :: e -> Parser e s Word8-hexWord8 e = Parser-  (\chunk0 s0 -> case hexSmallWordStart e 256 (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord8Result r #)-  )---- | Parse a hexadecimal-encoded 16-bit word. If the number is larger--- than 65535, this parser fails. This allows leading zeroes and is--- insensitive to case. For example, @0100a@ and @100A@ would both--- be accepted as the same number.-hexWord16 :: e -> Parser e s Word16-hexWord16 e = Parser-  (\chunk0 s0 -> case hexSmallWordStart e 65536 (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord16Result r #)-  )--hexWord32 :: e -> Parser e s Word32-hexWord32 e = Parser-  (\chunk0 s0 -> case hexSmallWordStart e 4294967296 (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord32Result r #)-  )---- | Parse a decimal-encoded 16-bit word. If the number is larger--- than 65535, this parser fails.-decWord16 :: e -> Parser e s Word16-decWord16 e = Parser-  (\chunk0 s0 -> case decSmallWordStart e 65536 (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord16Result r #)-  )---- | Parse a decimal-encoded 32-bit word. If the number is larger--- than 4294967295, this parser fails.-decWord32 :: e -> Parser e s Word32--- This will not work on 32-bit platforms.-decWord32 e = Parser-  (\chunk0 s0 -> case decSmallWordStart e 4294967296 (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord32Result r #)-  )---- | Parse a decimal-encoded number. If the number is too large to be--- represented by a machine word, this fails with the provided--- error message. This accepts any number of leading zeroes.-decWord :: e -> Parser e s Word-decWord e = Parser-  (\chunk0 s0 -> case decWordStart e (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWordResult r #)-  )---- | Parse a decimal-encoded unsigned number. If the number is--- too large to be represented by a 64-bit word, this fails with--- the provided error message. This accepts any number of leading--- zeroes.-decWord64 :: e -> Parser e s Word64-decWord64 e = Parser-  (\chunk0 s0 -> case decWordStart e (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastWord64Result r #)-  )--hexSmallWordStart ::-     e -- Error message-  -> Word -- Upper Bound-  -> Bytes -- Chunk-  -> ST# s (Result# e Word# )-hexSmallWordStart e !limit !chunk0 s0 = if length chunk0 > 0-  then case oneHexMaybe (PM.indexByteArray (array chunk0) (offset chunk0)) of-    Nothing -> (# s0, (# e | #) #)-    Just w -> (# s0, hexSmallWordMore e w limit (Bytes.unsafeDrop 1 chunk0) #)-  else (# s0, (# e | #) #)--decSmallWordStart ::-     e -- Error message-  -> Word -- Upper Bound-  -> Bytes -- Chunk-  -> ST# s (Result# e Word# )-decSmallWordStart e !limit !chunk0 s0 = if length chunk0 > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then (# s0, decSmallWordMore e w limit (Bytes.unsafeDrop 1 chunk0) #)-          else (# s0, (# e | #) #)-  else (# s0, (# e | #) #)---- This will not inline since it is recursive, but worker--- wrapper will still happen.-decWordMore ::-     e -- Error message-  -> Word -- Accumulator-  -> Bytes -- Chunk-  -> Result# e Word#-decWordMore e !acc !chunk0 = case len of-  0 -> (# | (# unW (fromIntegral acc), unI (offset chunk0), 0# #) #)-  _ ->-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then-            let (overflow,acc') = unsignedPushBase10 acc w-             in if overflow-               then (# e | #)-               else decWordMore e acc' (Bytes.unsafeDrop 1 chunk0)-          else (# | (# unW (fromIntegral acc), unI (offset chunk0), len# #) #)-  where-  !len@(I# len# ) = length chunk0--upcastWordResult :: Result# e Word# -> Result# e Word-{-# inline upcastWordResult #-}-upcastWordResult (# e | #) = (# e | #)-upcastWordResult (# | (# a, b, c #) #) = (# | (# W# a, b, c #) #)---- This only works on 64-bit platforms.-upcastWord64Result :: Result# e Word# -> Result# e Word64-{-# inline upcastWord64Result #-}-upcastWord64Result (# e | #) = (# e | #)-upcastWord64Result (# | (# a, b, c #) #) = (# | (# W64# (-#if MIN_VERSION_base(4,17,0)-    Exts.wordToWord64# a-#else-    a-#endif-    ), b, c #) #)--hexSmallWordMore ::-     e -- Error message-  -> Word -- Accumulator-  -> Word -- Upper Bound-  -> Bytes -- Chunk-  -> Result# e Word#-hexSmallWordMore e !acc !limit !chunk0 = if length chunk0 > 0-  then case oneHexMaybe (PM.indexByteArray (array chunk0) (offset chunk0)) of-    Nothing -> (# | (# unW acc, unI (offset chunk0), unI (length chunk0)  #) #)-    Just w -> let w' = acc * 16 + w in-      if w' < limit-        then hexSmallWordMore e w' limit (Bytes.unsafeDrop 1 chunk0)-        else (# e | #)-  else (# | (# unW acc, unI (offset chunk0), 0# #) #)--decSmallWordMore ::-     e -- Error message-  -> Word -- Accumulator-  -> Word -- Upper Bound-  -> Bytes -- Chunk-  -> Result# e Word#-decSmallWordMore e !acc !limit !chunk0 = if length chunk0 > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then-            let w' = acc * 10 + w-             in if w' < limit-                  then decSmallWordMore e w' limit (Bytes.unsafeDrop 1 chunk0)-                  else (# e | #)-          else (# | (# unW acc, unI (offset chunk0), unI (length chunk0)  #) #)-  else (# | (# unW acc, unI (offset chunk0), 0# #) #)--unW :: Word -> Word#-{-# inline unW #-}-unW (W# w) = w--decWordStart ::-     e -- Error message-  -> Bytes -- Chunk-  -> ST# s (Result# e Word# )-decWordStart e !chunk0 s0 = if length chunk0 > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then (# s0, decWordMore e w (Bytes.unsafeDrop 1 chunk0) #)-          else (# s0, (# e | #) #)-  else (# s0, (# e | #) #)---- Precondition: the word is small enough-upcastWord16Result :: Result# e Word# -> Result# e Word16-{-# inline upcastWord16Result #-}-upcastWord16Result (# e | #) = (# e | #)-upcastWord16Result (# | (# a, b, c #) #) = (# | (# W16# (-#if MIN_VERSION_base(4,16,0)-  Exts.wordToWord16#-#endif-  a), b, c #) #)---- Precondition: the word is small enough-upcastWord32Result :: Result# e Word# -> Result# e Word32-{-# inline upcastWord32Result #-}-upcastWord32Result (# e | #) = (# e | #)-upcastWord32Result (# | (# a, b, c #) #) = (# | (# W32# (-#if MIN_VERSION_base(4,16,0)-  Exts.wordToWord32#-#endif-  a), b, c #) #)---- Precondition: the word is small enough-upcastWord8Result :: Result# e Word# -> Result# e Word8-{-# inline upcastWord8Result #-}-upcastWord8Result (# e | #) = (# e | #)-upcastWord8Result (# | (# a, b, c #) #) = (# | (# W8# (-#if MIN_VERSION_base(4,16,0)-  Exts.wordToWord8#-#endif-  a), b, c #) #)---- | Parse a decimal-encoded number. If the number is too large to be--- represented by a machine integer, this fails with the provided--- error message. This rejects input with that is preceeded by plus--- or minus. Consequently, it does not parse negative numbers. Use--- 'decStandardInt' or 'decSignedInt' for that purpose. On a 64-bit--- platform 'decWord' will successfully parse 9223372036854775808--- (i.e. @2 ^ 63@), but 'decUnsignedInt' will fail. This parser allows--- leading zeroes.-decUnsignedInt :: e -> Parser e s Int-decUnsignedInt e = Parser-  (\chunk0 s0 -> case decPosIntStart e (boxBytes chunk0) s0 of-    (# s1, r #) -> (# s1, upcastIntResult r #)-  )---- | Variant of 'decUnsignedInt' with an unboxed result.-decUnsignedInt# :: e -> Parser e s Int#-decUnsignedInt# e = Parser-  (\chunk0 s0 -> decPosIntStart e (boxBytes chunk0) s0)---- | Parse a decimal-encoded number. If the number is too large to be--- represented by a machine integer, this fails with the provided--- error message. This allows the number to optionally be prefixed--- by plus or minus. If the sign prefix is not present, the number--- is interpreted as positive. This allows leading zeroes.-decSignedInt :: e -> Parser e s Int-decSignedInt e = Parser-  (\chunk0 s0 -> case runParser (decSignedInt# e) chunk0 s0 of-    (# s1, r #) -> (# s1, upcastIntResult r #)-  )---- | Variant of 'decUnsignedInt' that lets the caller supply a leading--- digit. This is useful when parsing formats like JSON where integers with--- leading zeroes are considered invalid. The calling context must--- consume the first digit before calling this parser. Results are--- always positive numbers.-decTrailingInt ::-     e -- ^ Error message-  -> Int -- ^ Leading digit, should be between @0@ and @9@.-  -> Parser e s Int-decTrailingInt e (I# w) = Parser-  (\chunk0 s0 -> case runParser (decTrailingInt# e w) chunk0 s0 of-    (# s1, r #) -> (# s1, upcastIntResult r #)-  )--decTrailingInt# ::-     e -- Error message-  -> Int# -- Leading digit, should be between @0@ and @9@.-  -> Parser e s Int#-decTrailingInt# e !w =-  Parser (\chunk0 s0 -> (# s0, decPosIntMore e (W# (int2Word# w)) maxIntAsWord (boxBytes chunk0) #))--maxIntAsWord :: Word-maxIntAsWord = fromIntegral (maxBound :: Int)---- | Parse a decimal-encoded number. If the number is too large to be--- represented by a machine integer, this fails with the provided--- error message. This allows the number to optionally be prefixed--- by minus. If the minus prefix is not present, the number--- is interpreted as positive. The disallows a leading plus sign.--- For example, 'decStandardInt' rejects @+42@, but 'decSignedInt'--- allows it.-decStandardInt :: e -> Parser e s Int-decStandardInt e = Parser-  (\chunk0 s0 -> case runParser (decStandardInt# e) chunk0 s0 of-    (# s1, r #) -> (# s1, upcastIntResult r #)-  )--decSignedInt# :: e -> Parser e s Int#-{-# noinline decSignedInt# #-}-decSignedInt# e = any e `bindFromLiftedToInt` \c -> case c of-  '+' -> Parser -- plus sign-    (\chunk0 s0 -> decPosIntStart e (boxBytes chunk0) s0)-  '-' -> Parser -- minus sign-    (\chunk0 s0 -> decNegIntStart e (boxBytes chunk0) s0)-  _ -> Parser -- no sign, there should be a digit here-    (\chunk0 s0 ->-      let !w = char2Word c - 48-        in if w < 10-             then (# s0, decPosIntMore e w maxIntAsWord (boxBytes chunk0) #)-             else (# s0, (# e | #) #)-    )---- This is the same as decSignedInt except that we disallow--- a leading plus sign.-decStandardInt# :: e -> Parser e s Int#-{-# noinline decStandardInt# #-}-decStandardInt# e = any e `bindFromLiftedToInt` \c -> case c of-  '-' -> Parser -- minus sign-    (\chunk0 s0 -> decNegIntStart e (boxBytes chunk0) s0)-  _ -> Parser -- no sign, there should be a digit here-    (\chunk0 s0 ->-      let !w = char2Word c - 48-        in if w < 10-             then (# s0, decPosIntMore e w maxIntAsWord (boxBytes chunk0) #)-             else (# s0, (# e | #) #)-    )---- | Variant of 'decUnsignedInteger' that lets the caller supply a leading--- digit. This is useful when parsing formats like JSON where integers with--- leading zeroes are considered invalid. The calling context must--- consume the first digit before calling this parser. Results are--- always positive numbers.-decTrailingInteger ::-     Int -- ^ Leading digit, should be between @0@ and @9@.-  -> Parser e s Integer-decTrailingInteger (I# w) =-  Parser (\chunk0 s0 -> (# s0, (# | decIntegerChunks (I# w) 10 0 (boxBytes chunk0) #) #))---- | Parse a decimal-encoded positive integer of arbitrary--- size. This rejects input that begins with a plus or minus--- sign.-decUnsignedInteger :: e -> Parser e s Integer-decUnsignedInteger e = Parser-  (\chunk0 s0 -> decUnsignedIntegerStart e (boxBytes chunk0) s0)---- | Parse a decimal-encoded integer of arbitrary size.--- This accepts input that begins with a plus or minus sign.--- Input without a sign prefix is interpreted as positive.-decSignedInteger :: e -> Parser e s Integer-{-# noinline decSignedInteger #-}-decSignedInteger e = any e >>= \c -> case c of-  '+' -> do-    decUnsignedInteger e-  '-' -> do-    x <- decUnsignedInteger e-    pure $! negate x-  _ -> Parser -- no sign, there should be a digit here-    (\chunk0 s0 ->-      let !w = char2Word c - 48 in-      if w < 10-        then-          let !r = decIntegerChunks-                (fromIntegral @Word @Int w)-                10-                0-                (boxBytes chunk0)-           in (# s0, (# | r #) #)-        else (# s0, (# e | #) #)-    )--decPosIntStart ::-     e -- Error message-  -> Bytes -- Chunk-  -> ST# s (Result# e Int# )-decPosIntStart e !chunk0 s0 = if length chunk0 > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then (# s0, decPosIntMore e w maxIntAsWord (Bytes.unsafeDrop 1 chunk0) #)-          else (# s0, (# e | #) #)-  else (# s0, (# e | #) #)--decNegIntStart ::-     e -- Error message-  -> Bytes -- Chunk-  -> ST# s (Result# e Int# )-decNegIntStart e !chunk0 s0 = if length chunk0 > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then-            case decPosIntMore e w (maxIntAsWord + 1) (Bytes.unsafeDrop 1 chunk0) of-             (# | (# x, y, z #) #) ->-               (# s0, (# | (# (notI# x +# 1# ), y, z #) #) #)-             (# err | #) ->-               (# s0, (# err | #) #)-          else (# s0, (# e | #) #)-  else (# s0, (# e | #) #)--decUnsignedIntegerStart ::-     e-  -> Bytes-  -> ST# s (Result# e Integer)-decUnsignedIntegerStart e !chunk0 s0 = if length chunk0 > 0-  then-    let !w = (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < (10 :: Word8)-          then-            let !r = decIntegerChunks-                  (fromIntegral @Word8 @Int w)-                  10-                  0-                  (Bytes.unsafeDrop 1 chunk0)-             in (# s0, (# | r #) #)-          else (# s0, (# e | #) #)-  else (# s0, (# e | #) #)---- This will not inline since it is recursive, but worker--- wrapper will still happen. Fails if the accumulator--- exceeds the upper bound.-decPosIntMore ::-     e -- Error message-  -> Word -- Accumulator, precondition: less than or equal to bound-  -> Word -- Inclusive Upper Bound, either (2^63 - 1) or 2^63-  -> Bytes -- Chunk-  -> Result# e Int#-decPosIntMore e !acc !upper !chunk0 = if len > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then-            let (overflow,acc') = positivePushBase10 acc w upper-             in if overflow-               then (# e | #)-               else decPosIntMore e acc' upper (Bytes.unsafeDrop 1 chunk0)-          else (# | (# unI (fromIntegral acc), unI (offset chunk0), len# #) #)-  else (# | (# unI (fromIntegral acc), unI (offset chunk0), 0# #) #)-  where-  !len@(I# len# ) = length chunk0---- This will not inline since it is recursive, but worker--- wrapper will still happen. When the accumulator--- exceeds the size of a machine integer, this pushes the--- accumulated machine int and the shift amount onto the--- stack.--- We are intentionally lazy in the accumulator. There is--- no need to force this on every iteration. We do however,--- force it preemptively every time it changes.--- Because of how we track overflow, we are able to use the--- same function for both positive and negative numbers.-decIntegerChunks ::-     Int -- Chunk accumulator (e.g. 236)-  -> Int -- Chunk base-ten bound (e.g. 1000)-  -> Integer -- Accumulator-  -> Bytes -- Chunk-  -> (# Integer, Int#, Int# #)-decIntegerChunks !nAcc !eAcc acc !chunk0 = if len > 0-  then-    let !w = fromIntegral @Word8 @Word-          (PM.indexByteArray (array chunk0) (offset chunk0)) - 48-     in if w < 10-          then let !eAcc' = eAcc * 10 in-            if eAcc' >= eAcc-              then decIntegerChunks-                (nAcc * 10 + fromIntegral @Word @Int w)-                eAcc'-                acc-                (Bytes.unsafeDrop 1 chunk0)-              else-                -- In this case, notice that we deliberately-                -- unconsume the digit that would have caused-                -- an overflow.-                let !r = (acc * fromIntegral @Int @Integer eAcc)-                       + (fromIntegral @Int @Integer nAcc)-                 in decIntegerChunks 0 1 r chunk0-          else-            let !r = (acc * fromIntegral @Int @Integer eAcc)-                   + (fromIntegral @Int @Integer nAcc)-             in (# r, unI (offset chunk0), len# #)-  else-    let !r = (acc * fromIntegral @Int @Integer eAcc)-           + (fromIntegral @Int @Integer nAcc)-     in (# r, unI (offset chunk0), 0# #)-  where-  !len@(I# len# ) = length chunk0--upcastIntResult :: Result# e Int# -> Result# e Int-upcastIntResult (# e | #) = (# e | #)-upcastIntResult (# | (# a, b, c #) #) = (# | (# I# a, b, c #) #)--char2Word :: Char -> Word-char2Word = fromIntegral . ord---- | Take characters until the specified character is encountered.--- Consumes the matched character as well. Fails if the character--- is not present.  Visually, the cursor advancement and resulting--- @Bytes@ for @takeTrailedBy \'D\'@ look like this:------ >  A B C D E F | input--- > |->->->-|    | cursor--- > {-*-*-}      | result bytes-takeTrailedBy :: e -> Char -> Parser e s Bytes-takeTrailedBy e !w = do-  !start <- cursor-  skipTrailedBy e w-  !end <- cursor-  !arr <- expose-  pure (Bytes arr start (end - (start + 1)))---- | Skip all characters until the terminator is encountered--- and then consume the matching character as well. Visually,--- @skipTrailedBy \'C\'@ advances the cursor like this:------ >  A Z B Y C X C W--- > |->->->->-|------ This fails if it reaches the end of input without encountering--- the character.-skipTrailedBy :: e -> Char -> Parser e s ()-skipTrailedBy e !w = uneffectful# $ \c ->-  skipUntilConsumeLoop e w c---- | Skip all characters until the terminator is encountered.--- This does not consume the terminator. Visually, @skipUntil \'C\'@--- advances the cursor like this:------ >  A Z B Y C X C W--- > |->->->-|------ This succeeds if it reaches the end of the input without--- encountering the terminator. It never fails.-skipUntil :: Char -> Parser e s ()-skipUntil !w = uneffectful# $ \c -> skipUntilLoop w c--skipUntilLoop ::-     Char -- byte to match-  -> Bytes -- Chunk-  -> Result# e ()-skipUntilLoop !w !c = case length c of-  0 -> (# | (# (), unI (offset c), 0# #) #)-  _ -> if indexLatinCharArray (array c) (offset c) /= w-    then skipUntilLoop w (Bytes.unsafeDrop 1 c)-    else (# | (# (), unI (offset c), unI (length c) #) #)--skipUntilConsumeLoop ::-     e -- Error message-  -> Char -- byte to match-  -> Bytes -- Chunk-  -> Result# e ()-skipUntilConsumeLoop e !w !c = case length c of-  0 -> (# e | #)-  _ -> if indexLatinCharArray (array c) (offset c) /= w-    then skipUntilConsumeLoop e w (Bytes.unsafeDrop 1 c)-    else (# | (# (), unI (offset c + 1), unI (length c - 1) #) #)----- | Parse exactly eight ASCII-encoded characters, interpreting them as the--- hexadecimal encoding of a 32-bit number. Note that this rejects a sequence--- such as @BC5A9@, requiring @000BC5A9@ instead. This is insensitive to case.-hexFixedWord32 :: e -> Parser e s Word32-{-# inline hexFixedWord32 #-}-hexFixedWord32 e = Parser-  (\x s0 -> case runParser (hexFixedWord32# e) x s0 of-    (# s1, r #) -> case r of-      (# err | #) -> (# s1, (# err | #) #)-      (# | (# a, b, c #) #) -> (# s1, (# | (# W32# (-#if MIN_VERSION_base(4,16,0)-        Exts.wordToWord32#-#endif-        a), b, c #) #) #)-  )--hexFixedWord32# :: e -> Parser e s Word#-{-# noinline hexFixedWord32# #-}-hexFixedWord32# e = uneffectfulWord# $ \chunk -> if length chunk >= 8-  then-    let !w0@(W# n0) = oneHex $ PM.indexByteArray (array chunk) (offset chunk)-        !w1@(W# n1) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 1)-        !w2@(W# n2) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 2)-        !w3@(W# n3) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 3)-        !w4@(W# n4) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 4)-        !w5@(W# n5) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 5)-        !w6@(W# n6) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 6)-        !w7@(W# n7) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 7)-     in if | w0 .|. w1 .|. w2 .|. w3 .|. w4 .|. w5 .|. w6 .|. w7 /= maxBound ->-             (# |-                (# (n0 `Exts.timesWord#` 268435456##) `Exts.plusWord#`-                   (n1 `Exts.timesWord#` 16777216##) `Exts.plusWord#`-                   (n2 `Exts.timesWord#` 1048576##) `Exts.plusWord#`-                   (n3 `Exts.timesWord#` 65536##) `Exts.plusWord#`-                   (n4 `Exts.timesWord#` 4096##) `Exts.plusWord#`-                   (n5 `Exts.timesWord#` 256##) `Exts.plusWord#`-                   (n6 `Exts.timesWord#` 16##) `Exts.plusWord#`-                   n7-                ,  unI (offset chunk) +# 8#-                ,  unI (length chunk) -# 8# #) #)-           | otherwise -> (# e | #)-  else (# e | #)---- | Parse exactly 16 ASCII-encoded characters, interpreting them as the--- hexadecimal encoding of a 64-bit number. Note that this rejects a sequence--- such as @BC5A9@, requiring @00000000000BC5A9@ instead. This is insensitive--- to case.-hexFixedWord64 :: e -> Parser e s Word64-{-# inline hexFixedWord64 #-}-hexFixedWord64 e = Parser-  (\x s0 -> case runParser (hexFixedWord64# e) x s0 of-    (# s1, r #) -> case r of-      (# err | #) -> (# s1, (# err | #) #)-      (# | (# a, b, c #) #) -> (# s1, (# | (# W64# (-#if MIN_VERSION_base(4,17,0)-          Exts.wordToWord64# a-#else--          a-#endif-          ), b, c #) #) #)-  )--hexFixedWord128 :: e -> Parser e s Word128-hexFixedWord128 e = Word128-  <$> hexFixedWord64 e-  <*> hexFixedWord64 e--hexFixedWord256 :: e -> Parser e s Word256-hexFixedWord256 e = Word256-  <$> hexFixedWord64 e-  <*> hexFixedWord64 e-  <*> hexFixedWord64 e-  <*> hexFixedWord64 e--hexFixedWord64# :: e -> Parser e s Word#-{-# noinline hexFixedWord64# #-}-hexFixedWord64# e = uneffectfulWord# $ \chunk -> if length chunk >= 16-  then-    let go !off !len !acc = case len of-          0 -> case acc of-            W# r ->-              (# | (# r-              ,  unI off-              ,  unI (length chunk) -# 16# #) #)-          _ -> case oneHexMaybe (PM.indexByteArray (array chunk) off) of-            Nothing -> (# e | #)-            Just w -> go (off + 1) (len - 1) ((acc * 16) + w)-     in go (offset chunk) (16 :: Int) (0 :: Word)-  else (# e | #)---- | Parse exactly four ASCII-encoded characters, interpreting--- them as the hexadecimal encoding of a 16-bit number. Note that--- this rejects a sequence such as @5A9@, requiring @05A9@ instead.--- This is insensitive to case. This is particularly useful when--- parsing escape sequences in C or JSON, which allow encoding--- characters in the Basic Multilingual Plane as @\\uhhhh@.-hexFixedWord16 :: e -> Parser e s Word16-{-# inline hexFixedWord16 #-}-hexFixedWord16 e = Parser-  (\x s0 -> case runParser (hexFixedWord16# e) x s0 of-    (# s1, r #) -> case r of-      (# err | #) -> (# s1, (# err | #) #)-      (# | (# a, b, c #) #) -> (# s1, (# | (# W16# (-#if MIN_VERSION_base(4,16,0)-        Exts.wordToWord16#-#endif-        a), b, c #) #) #)-  )--hexFixedWord16# :: e -> Parser e s Word#-{-# noinline hexFixedWord16# #-}-hexFixedWord16# e = uneffectfulWord# $ \chunk -> if length chunk >= 4-  then-    let !w0@(W# n0) = oneHex $ PM.indexByteArray (array chunk) (offset chunk)-        !w1@(W# n1) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 1)-        !w2@(W# n2) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 2)-        !w3@(W# n3) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 3)-     in if | w0 .|. w1 .|. w2 .|. w3 /= maxBound ->-             (# |-                (# (n0 `Exts.timesWord#` 4096##) `Exts.plusWord#`-                   (n1 `Exts.timesWord#` 256##) `Exts.plusWord#`-                   (n2 `Exts.timesWord#` 16##) `Exts.plusWord#`-                   n3-                ,  unI (offset chunk) +# 4#-                ,  unI (length chunk) -# 4# #) #)-           | otherwise -> (# e | #)-  else (# e | #)---- | Parse exactly two ASCII-encoded characters, interpretting--- them as the hexadecimal encoding of a 8-bit number. Note that--- this rejects a sequence such as @A@, requiring @0A@ instead.--- This is insensitive to case.-hexFixedWord8 :: e -> Parser e s Word8-{-# inline hexFixedWord8 #-}-hexFixedWord8 e = Parser-  (\x s0 -> case runParser (hexFixedWord8# e) x s0 of-    (# s1, r #) -> case r of-      (# err | #) -> (# s1, (# err | #) #)-      (# | (# a, b, c #) #) -> (# s1, (# | (# W8# (-#if MIN_VERSION_base(4,16,0)-        Exts.wordToWord8#-#endif-        a), b, c #) #) #)-  )--hexFixedWord8# :: e -> Parser e s Word#-{-# noinline hexFixedWord8# #-}-hexFixedWord8# e = uneffectfulWord# $ \chunk -> if length chunk >= 2-  then-    let !w0@(W# n0) = oneHex $ PM.indexByteArray (array chunk) (offset chunk)-        !w1@(W# n1) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 1)-     in if | w0 .|. w1 /= maxBound ->-             (# |-                (# (n0 `Exts.timesWord#` 16##) `Exts.plusWord#`-                   n1-                ,  unI (offset chunk) +# 2#-                ,  unI (length chunk) -# 2# #) #)-           | otherwise -> (# e | #)-  else (# e | #)---- | Consume a single character that is the lowercase hexadecimal--- encoding of a 4-bit word. Fails if the character is not in the class--- @[a-f0-9]@.-hexNibbleLower :: e -> Parser e s Word-hexNibbleLower e = uneffectful $ \chunk -> case length chunk of-  0 -> Failure e-  _ ->-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8 in-    if | w >= 48 && w < 58 -> Success (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)-       | w >= 97 && w < 103 -> Success (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)-       | otherwise -> Failure e---- | Consume a single character that is the case-insensitive hexadecimal--- encoding of a 4-bit word. Fails if the character is not in the class--- @[a-fA-F0-9]@.-hexNibble :: e -> Parser e s Word-hexNibble e = uneffectful $ \chunk -> case length chunk of-  0 -> Failure e-  _ ->-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8 in-    if | w >= 48 && w < 58 -> Success (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)-       | w >= 65 && w < 71 -> Success (fromIntegral w - 55) (offset chunk + 1) (length chunk - 1)-       | w >= 97 && w < 103 -> Success (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)-       | otherwise -> Failure e---- | Consume a single character that is the lowercase hexadecimal--- encoding of a 4-bit word. Returns @Nothing@ without consuming--- the character if it is not in the class @[a-f0-9]@. The parser--- never fails.-tryHexNibbleLower :: Parser e s (Maybe Word)-tryHexNibbleLower = unfailing $ \chunk -> case length chunk of-  0 -> InternalStep Nothing (offset chunk) (length chunk)-  _ ->-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8 in-    if | w >= 48 && w < 58 -> InternalStep (Just (fromIntegral w - 48)) (offset chunk + 1) (length chunk - 1)-       | w >= 97 && w < 103 -> InternalStep (Just (fromIntegral w - 87)) (offset chunk + 1) (length chunk - 1)-       | otherwise -> InternalStep Nothing (offset chunk) (length chunk)---- | Consume a single character that is the case-insensitive hexadecimal--- encoding of a 4-bit word. Returns @Nothing@ without consuming--- the character if it is not in the class @[a-fA-F0-9]@. This parser--- never fails.-tryHexNibble :: Parser e s (Maybe Word)-tryHexNibble = unfailing $ \chunk -> case length chunk of-  0 -> InternalStep Nothing (offset chunk) (length chunk)-  _ ->-    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8 in-    if | w >= 48 && w < 58 -> InternalStep (Just (fromIntegral w - 48)) (offset chunk + 1) (length chunk - 1)-       | w >= 65 && w < 71 -> InternalStep (Just (fromIntegral w - 55)) (offset chunk + 1) (length chunk - 1)-       | w >= 97 && w < 103 -> InternalStep (Just (fromIntegral w - 87)) (offset chunk + 1) (length chunk - 1)-       | otherwise -> InternalStep Nothing (offset chunk) (length chunk)---- Returns the maximum machine word if the argument is not--- the ASCII encoding of a hexadecimal digit.-oneHex :: Word8 -> Word-{-# inline oneHex #-}-oneHex w-  | w >= 48 && w < 58 = (fromIntegral w - 48)-  | w >= 65 && w < 71 = (fromIntegral w - 55)-  | w >= 97 && w < 103 = (fromIntegral w - 87)-  | otherwise = maxBound--oneHexMaybe :: Word8 -> Maybe Word-{-# inline oneHexMaybe #-}-oneHexMaybe w-  | w >= 48 && w < 58 = Just (fromIntegral w - 48)-  | w >= 65 && w < 71 = Just (fromIntegral w - 55)-  | w >= 97 && w < 103 = Just (fromIntegral w - 87)-  | otherwise = Nothing--uneffectfulWord# :: (Bytes -> Result# e Word#) -> Parser e s Word#-{-# inline uneffectfulWord# #-}-uneffectfulWord# f = Parser-  ( \b s0 -> (# s0, (f (boxBytes b)) #) )---- Precondition: the arguments are non-negative. Boolean is--- true when overflow happens. Performs: a * 10 + b--- Postcondition: when overflow is false, the resulting--- word is less than or equal to the upper bound-positivePushBase10 :: Word -> Word -> Word -> (Bool,Word)-{-# inline positivePushBase10 #-}-positivePushBase10 (W# a) (W# b) (W# upper) =-  let !(# ca, r0 #) = Exts.timesWord2# a 10##-      !r1 = Exts.plusWord# r0 b-      !cb = int2Word# (gtWord# r1 upper)-      !cc = int2Word# (ltWord# r1 0##)-      !c = ca `or#` cb `or#` cc-   in (case c of { 0## -> False; _ -> True }, W# r1)--unsignedPushBase10 :: Word -> Word -> (Bool,Word)-{-# inline unsignedPushBase10 #-}-unsignedPushBase10 (W# a) (W# b) =-  let !(# ca, r0 #) = Exts.timesWord2# a 10##-      !r1 = Exts.plusWord# r0 b-      !cb = int2Word# (ltWord# r1 r0)-      !c = ca `or#` cb-   in (case c of { 0## -> False; _ -> True }, W# r1)---- | Skip while the predicate is matched. This is always inlined.-skipWhile :: (Char -> Bool) -> Parser e s ()-{-# inline skipWhile #-}-skipWhile f = go where-  go = isEndOfInput >>= \case-    True -> pure ()-    False -> do-      w <- anyUnsafe-      if f w-        then go-        else unconsume 1---- Interpret the next byte as an Latin1-encoded character.--- Does not check to see if any characters are left. This--- is not exported.-anyUnsafe :: Parser e s Char-{-# inline anyUnsafe #-}-anyUnsafe = uneffectful $ \chunk ->-  let w = indexCharArray (array chunk) (offset chunk) :: Char-   in Success w (offset chunk + 1) (length chunk - 1)---- Reads one byte and interprets it as Latin1-encoded character.-indexCharArray :: PM.ByteArray -> Int -> Char-{-# inline indexCharArray #-}-indexCharArray (PM.ByteArray x) (I# i) = C# (indexCharArray# x i)---- | Match any character, to perform lookahead. Returns 'Nothing' if---   end of input has been reached. Does not consume any input.------   /Note/: Because this parser does not fail, do not use it---   with combinators such as 'many', because such as 'many',---   because such parsers loop until a failure occurs. Careless---   use will thus result in an infinite loop.-peek :: Parser e s (Maybe Char)-{-# inline peek #-}-peek = uneffectful $ \(Bytes arr off len) ->-  let v = if len > 0-        then Just (indexCharArray arr off)-        else Nothing-  in Success v off len---- | Match any byte, to perform lookahead. Does not consume any---   input, but will fail if end of input has been reached.-peek' :: e -> Parser e s Char-{-# inline peek' #-}-peek' e = uneffectful $ \(Bytes arr off len) -> if len > 0-  then Success (indexCharArray arr off) off len-  else Failure e+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UnboxedSums #-}+{-# LANGUAGE UnboxedTuples #-}++{- | Parse input as though it were text encoded by+ISO 8859-1 (Latin-1). All byte sequences are valid+text under ISO 8859-1.+-}+module Data.Bytes.Parser.Latin+  ( -- * Matching++    -- ** Required+    char+  , char2+  , char3+  , char4+  , char5+  , char6+  , char7+  , char8+  , char9+  , char10+  , char11+  , char12++    -- ** Try+  , trySatisfy+  , trySatisfyThen++    -- * One Character+  , any+  , opt+  , opt#++    -- * Many Characters+  , takeTrailedBy++    -- * Lookahead+  , peek+  , peek'++    -- * Skip+  , skipDigits+  , skipDigits1+  , skipChar+  , skipChar1+  , skipTrailedBy+  , skipUntil+  , skipWhile++    -- * End of Input+  , endOfInput+  , isEndOfInput++    -- * Numbers++    -- ** Decimal++    -- *** Unsigned+  , decWord+  , decWord8+  , decWord16+  , decWord32+  , decWord64++    -- *** Signed+  , decUnsignedInt+  , decUnsignedInt#+  , decSignedInt+  , decStandardInt+  , decTrailingInt+  , decTrailingInt#+  , decSignedInteger+  , decUnsignedInteger+  , decTrailingInteger++    -- ** Hexadecimal++    -- *** Variable Length+  , hexWord8+  , hexWord16+  , hexWord32++    -- *** Fixed Length+  , hexFixedWord8+  , hexFixedWord16+  , hexFixedWord32+  , hexFixedWord64+  , hexFixedWord128+  , hexFixedWord256++    -- *** Digit+  , hexNibbleLower+  , tryHexNibbleLower+  , hexNibble+  , tryHexNibble+  ) where++import Prelude hiding (any, fail, length, takeWhile)++import Data.Bits ((.|.))+import Data.Bytes.Parser (bindFromLiftedToInt, endOfInput, isEndOfInput)+import Data.Bytes.Parser.Internal (InternalStep (..), Parser (..), Result (..), Result#, ST#, boxBytes, indexLatinCharArray, uneffectful, uneffectful#, unfailing, upcastUnitSuccess)+import Data.Bytes.Parser.Unsafe (cursor, expose, unconsume)+import Data.Bytes.Types (Bytes (..))+import Data.Char (ord)+import Data.Kind (Type)+import Data.WideWord (Word128 (Word128), Word256 (Word256))+import Data.Word (Word8)+import GHC.Exts (Char (C#), Char#, Int (I#), Int#, RuntimeRep, TYPE, Word#, gtWord#, indexCharArray#, int2Word#, ltWord#, notI#, or#, (+#), (-#))+import GHC.Word (Word (W#), Word16 (W16#), Word32 (W32#), Word64 (W64#), Word8 (W8#))++import qualified Data.Bytes as Bytes+import qualified Data.Primitive as PM+import qualified GHC.Exts as Exts++{- | Runs the predicate on the next character in the input. If the+predicate is matched, this consumes the character. Otherwise,+the character is not consumed. This returns @False@ if the end+of the input has been reached. This never fails.+-}+trySatisfy :: (Char -> Bool) -> Parser e s Bool+trySatisfy f = uneffectful $ \chunk -> case length chunk of+  0 -> Success False (offset chunk) (length chunk)+  _ -> case f (indexLatinCharArray (array chunk) (offset chunk)) of+    True -> Success True (offset chunk + 1) (length chunk - 1)+    False -> Success False (offset chunk) (length chunk)++{- | Runs the function on the next character in the input. If the+function returns @Just@, this consumes the character and then+runs the parser on the remaining input. If the function returns+@Nothing@, this does not consume the tested character, and it+runs the default parser on the input (which includes the tested+character). If there is no input remaining, this also runs the+default parser. This combinator never fails.+-}+trySatisfyThen ::+  forall (r :: RuntimeRep) (e :: Type) (s :: Type) (a :: TYPE r).+  -- | Default parser. Runs on @Nothing@ or end of input.+  Parser e s a ->+  -- | Parser-selecting predicate+  (Char -> Maybe (Parser e s a)) ->+  Parser e s a+{-# INLINE trySatisfyThen #-}+trySatisfyThen (Parser g) f =+  Parser+    ( \input@(# arr, off0, len0 #) s0 -> case len0 of+        0# -> g input s0+        _ -> case f (C# (indexCharArray# arr off0)) of+          Nothing -> g input s0+          Just (Parser p) -> p (# arr, off0 +# 1#, len0 -# 1# #) s0+    )++{- | Consume the next character, failing if it does not+match the expected value or if there is no more input.+-}+char :: e -> Char -> Parser e s ()+{-# INLINE char #-}+char e !c = uneffectful $ \chunk ->+  if length chunk > 0+    then+      if indexLatinCharArray (array chunk) (offset chunk) == c+        then Success () (offset chunk + 1) (length chunk - 1)+        else Failure e+    else Failure e++{- | Consume the next two characters, failing if they do+not match the expected values.++> char2 e a b === char e a *> char e b+-}+char2 :: e -> Char -> Char -> Parser e s ()+{-# INLINE char2 #-}+char2 e !c0 !c1 = uneffectful $ \chunk ->+  if+    | length chunk > 1+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1 ->+        Success () (offset chunk + 2) (length chunk - 2)+    | otherwise -> Failure e++{- | Consume three characters, failing if they do+not match the expected values.++> char3 e a b c === char e a *> char e b *> char e c+-}+char3 :: e -> Char -> Char -> Char -> Parser e s ()+{-# INLINE char3 #-}+char3 e !c0 !c1 !c2 = uneffectful $ \chunk ->+  if+    | length chunk > 2+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2 ->+        Success () (offset chunk + 3) (length chunk - 3)+    | otherwise -> Failure e++{- | Consume four characters, failing if they do+not match the expected values.++> char4 e a b c d === char e a *> char e b *> char e c *> char e d+-}+char4 :: e -> Char -> Char -> Char -> Char -> Parser e s ()+{-# INLINE char4 #-}+char4 e !c0 !c1 !c2 !c3 = uneffectful $ \chunk ->+  if+    | length chunk > 3+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3 ->+        Success () (offset chunk + 4) (length chunk - 4)+    | otherwise -> Failure e++{- | Consume five characters, failing if they do+not match the expected values.+-}+char5 :: e -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# INLINE char5 #-}+char5 e !c0 !c1 !c2 !c3 !c4 = uneffectful $ \chunk ->+  if+    | length chunk > 4+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4 ->+        Success () (offset chunk + 5) (length chunk - 5)+    | otherwise -> Failure e++{- | Consume six characters, failing if they do+not match the expected values.+-}+char6 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# INLINE char6 #-}+char6 e !c0 !c1 !c2 !c3 !c4 !c5 = uneffectful $ \chunk ->+  if+    | length chunk > 5+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5 ->+        Success () (offset chunk + 6) (length chunk - 6)+    | otherwise -> Failure e++{- | Consume seven characters, failing if they do+not match the expected values.+-}+char7 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# INLINE char7 #-}+char7 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 = uneffectful $ \chunk ->+  if+    | length chunk > 6+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5+    , indexLatinCharArray (array chunk) (offset chunk + 6) == c6 ->+        Success () (offset chunk + 7) (length chunk - 7)+    | otherwise -> Failure e++{- | Consume eight characters, failing if they do+not match the expected values.+-}+char8 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# INLINE char8 #-}+char8 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 = uneffectful $ \chunk ->+  if+    | length chunk > 7+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5+    , indexLatinCharArray (array chunk) (offset chunk + 6) == c6+    , indexLatinCharArray (array chunk) (offset chunk + 7) == c7 ->+        Success () (offset chunk + 8) (length chunk - 8)+    | otherwise -> Failure e++{- | Consume nine characters, failing if they do+not match the expected values.+-}+char9 ::+  e ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Parser e s ()+{-# INLINE char9 #-}+char9 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 = uneffectful $ \chunk ->+  if+    | length chunk > 8+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5+    , indexLatinCharArray (array chunk) (offset chunk + 6) == c6+    , indexLatinCharArray (array chunk) (offset chunk + 7) == c7+    , indexLatinCharArray (array chunk) (offset chunk + 8) == c8 ->+        Success () (offset chunk + 9) (length chunk - 9)+    | otherwise -> Failure e++{- | Consume ten characters, failing if they do+not match the expected values.+-}+char10 ::+  e ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Parser e s ()+{-# INLINE char10 #-}+char10 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 = uneffectful $ \chunk ->+  if+    | length chunk > 9+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5+    , indexLatinCharArray (array chunk) (offset chunk + 6) == c6+    , indexLatinCharArray (array chunk) (offset chunk + 7) == c7+    , indexLatinCharArray (array chunk) (offset chunk + 8) == c8+    , indexLatinCharArray (array chunk) (offset chunk + 9) == c9 ->+        Success () (offset chunk + 10) (length chunk - 10)+    | otherwise -> Failure e++{- | Consume eleven characters, failing if they do+not match the expected values.+-}+char11 ::+  e ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Parser e s ()+{-# INLINE char11 #-}+char11 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 !c10 = uneffectful $ \chunk ->+  if+    | length chunk > 10+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5+    , indexLatinCharArray (array chunk) (offset chunk + 6) == c6+    , indexLatinCharArray (array chunk) (offset chunk + 7) == c7+    , indexLatinCharArray (array chunk) (offset chunk + 8) == c8+    , indexLatinCharArray (array chunk) (offset chunk + 9) == c9+    , indexLatinCharArray (array chunk) (offset chunk + 10) == c10 ->+        Success () (offset chunk + 11) (length chunk - 11)+    | otherwise -> Failure e++{- | Consume twelve characters, failing if they do+not match the expected values.+-}+char12 ::+  e ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Char ->+  Parser e s ()+{-# INLINE char12 #-}+char12 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 !c10 !c11 = uneffectful $ \chunk ->+  if+    | length chunk > 11+    , indexLatinCharArray (array chunk) (offset chunk) == c0+    , indexLatinCharArray (array chunk) (offset chunk + 1) == c1+    , indexLatinCharArray (array chunk) (offset chunk + 2) == c2+    , indexLatinCharArray (array chunk) (offset chunk + 3) == c3+    , indexLatinCharArray (array chunk) (offset chunk + 4) == c4+    , indexLatinCharArray (array chunk) (offset chunk + 5) == c5+    , indexLatinCharArray (array chunk) (offset chunk + 6) == c6+    , indexLatinCharArray (array chunk) (offset chunk + 7) == c7+    , indexLatinCharArray (array chunk) (offset chunk + 8) == c8+    , indexLatinCharArray (array chunk) (offset chunk + 9) == c9+    , indexLatinCharArray (array chunk) (offset chunk + 10) == c10+    , indexLatinCharArray (array chunk) (offset chunk + 11) == c11 ->+        Success () (offset chunk + 12) (length chunk - 12)+    | otherwise -> Failure e++-- | Consumes and returns the next character in the input.+any :: e -> Parser e s Char+{-# INLINE any #-}+any e = uneffectful $ \chunk ->+  if length chunk > 0+    then+      let c = indexLatinCharArray (array chunk) (offset chunk)+       in Success c (offset chunk + 1) (length chunk - 1)+    else Failure e++{- | Consume a character from the input or return @Nothing@ if+end of the stream has been reached. Since ISO 8859-1 maps every+bytes to a character, this parser never fails.+-}+opt :: Parser e s (Maybe Char)+{-# INLINE opt #-}+opt = uneffectful $ \chunk -> case length chunk of+  0 -> Success Nothing (offset chunk) (length chunk)+  _ ->+    Success+      (Just (indexLatinCharArray (array chunk) (offset chunk)))+      (offset chunk + 1)+      (length chunk - 1)++-- | Variant of @opt@ with unboxed result.+opt# :: Parser e s (# (# #) | Char# #)+{-# INLINE opt# #-}+opt# =+  Parser+    ( \(# arr, off, len #) s0 -> case len of+        0# -> (# s0, (# | (# (# (# #) | #), off, len #) #) #)+        _ -> (# s0, (# | (# (# | indexCharArray# arr off #), off +# 1#, len -# 1# #) #) #)+    )++skipDigitsAsciiLoop ::+  Bytes -> -- Chunk+  (# Int#, Int# #)+skipDigitsAsciiLoop !c =+  if length c > 0+    then+      let w = indexLatinCharArray (array c) (offset c)+       in if w >= '0' && w <= '9'+            then skipDigitsAsciiLoop (Bytes.unsafeDrop 1 c)+            else (# unI (offset c), unI (length c) #)+    else (# unI (offset c), unI (length c) #)++skipDigitsAscii1LoopStart ::+  e ->+  Bytes -> -- chunk+  Result# e ()+skipDigitsAscii1LoopStart e !c =+  if length c > 0+    then+      let w = indexLatinCharArray (array c) (offset c)+       in if w >= '0' && w <= '9'+            then upcastUnitSuccess (skipDigitsAsciiLoop (Bytes.unsafeDrop 1 c))+            else (# e | #)+    else (# e | #)++{- | Variant of 'skipDigits' that requires at least one digit+to be present.+-}+skipDigits1 :: e -> Parser e s ()+{-# INLINE skipDigits1 #-}+skipDigits1 e = uneffectful# $ \c ->+  skipDigitsAscii1LoopStart e c++{- | Skip the characters @0-9@ until a non-digit is encountered.+This parser does not fail.+-}+skipDigits :: Parser e s ()+skipDigits = uneffectful# $ \c ->+  upcastUnitSuccess (skipDigitsAsciiLoop c)++unI :: Int -> Int#+{-# INLINE unI #-}+unI (I# w) = w++{- | Skip the character any number of times. This succeeds+even if the character was not present.+-}+skipChar :: Char -> Parser e s ()+{-# INLINE skipChar #-}+skipChar !w = uneffectful# $ \c ->+  upcastUnitSuccess (skipLoop w c)++{- | Skip the character any number of times. It must occur+at least once or else this will fail.+-}+skipChar1 :: e -> Char -> Parser e s ()+{-# INLINE skipChar1 #-}+skipChar1 e !w = uneffectful# $ \c ->+  skipLoop1Start e w c++skipLoop ::+  Char -> -- byte to match+  Bytes -> -- Chunk+  (# Int#, Int# #)+skipLoop !w !c =+  if length c > 0+    then+      if indexLatinCharArray (array c) (offset c) == w+        then skipLoop w (Bytes.unsafeDrop 1 c)+        else (# unI (offset c), unI (length c) #)+    else (# unI (offset c), unI (length c) #)++skipLoop1Start ::+  e ->+  Char -> -- byte to match+  Bytes -> -- chunk+  Result# e ()+skipLoop1Start e !w !chunk0 =+  if length chunk0 > 0+    then+      if indexLatinCharArray (array chunk0) (offset chunk0) == w+        then upcastUnitSuccess (skipLoop w (Bytes.unsafeDrop 1 chunk0))+        else (# e | #)+    else (# e | #)++{- | Parse a decimal-encoded 8-bit word. If the number is larger+than 255, this parser fails.+-}+decWord8 :: e -> Parser e s Word8+decWord8 e =+  Parser+    ( \chunk0 s0 -> case decSmallWordStart e 256 (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord8Result r #)+    )++{- | Parse a hexadecimal-encoded 8-bit word. If the number is larger+than 255, this parser fails. This allows leading zeroes and is+insensitive to case. For example, @00A@, @0a@ and @A@ would all+be accepted as the same number.+-}+hexWord8 :: e -> Parser e s Word8+hexWord8 e =+  Parser+    ( \chunk0 s0 -> case hexSmallWordStart e 256 (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord8Result r #)+    )++{- | Parse a hexadecimal-encoded 16-bit word. If the number is larger+than 65535, this parser fails. This allows leading zeroes and is+insensitive to case. For example, @0100a@ and @100A@ would both+be accepted as the same number.+-}+hexWord16 :: e -> Parser e s Word16+hexWord16 e =+  Parser+    ( \chunk0 s0 -> case hexSmallWordStart e 65536 (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord16Result r #)+    )++hexWord32 :: e -> Parser e s Word32+hexWord32 e =+  Parser+    ( \chunk0 s0 -> case hexSmallWordStart e 4294967296 (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord32Result r #)+    )++{- | Parse a decimal-encoded 16-bit word. If the number is larger+than 65535, this parser fails.+-}+decWord16 :: e -> Parser e s Word16+decWord16 e =+  Parser+    ( \chunk0 s0 -> case decSmallWordStart e 65536 (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord16Result r #)+    )++{- | Parse a decimal-encoded 32-bit word. If the number is larger+than 4294967295, this parser fails.+-}+decWord32 :: e -> Parser e s Word32+-- This will not work on 32-bit platforms.+decWord32 e =+  Parser+    ( \chunk0 s0 -> case decSmallWordStart e 4294967296 (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord32Result r #)+    )++{- | Parse a decimal-encoded number. If the number is too large to be+represented by a machine word, this fails with the provided+error message. This accepts any number of leading zeroes.+-}+decWord :: e -> Parser e s Word+decWord e =+  Parser+    ( \chunk0 s0 -> case decWordStart e (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWordResult r #)+    )++{- | Parse a decimal-encoded unsigned number. If the number is+too large to be represented by a 64-bit word, this fails with+the provided error message. This accepts any number of leading+zeroes.+-}+decWord64 :: e -> Parser e s Word64+decWord64 e =+  Parser+    ( \chunk0 s0 -> case decWordStart e (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastWord64Result r #)+    )++hexSmallWordStart ::+  e -> -- Error message+  Word -> -- Upper Bound+  Bytes -> -- Chunk+  ST# s (Result# e Word#)+hexSmallWordStart e !limit !chunk0 s0 =+  if length chunk0 > 0+    then case oneHexMaybe (PM.indexByteArray (array chunk0) (offset chunk0)) of+      Nothing -> (# s0, (# e | #) #)+      Just w -> (# s0, hexSmallWordMore e w limit (Bytes.unsafeDrop 1 chunk0) #)+    else (# s0, (# e | #) #)++decSmallWordStart ::+  e -> -- Error message+  Word -> -- Upper Bound+  Bytes -> -- Chunk+  ST# s (Result# e Word#)+decSmallWordStart e !limit !chunk0 s0 =+  if length chunk0 > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then (# s0, decSmallWordMore e w limit (Bytes.unsafeDrop 1 chunk0) #)+            else (# s0, (# e | #) #)+    else (# s0, (# e | #) #)++-- This will not inline since it is recursive, but worker+-- wrapper will still happen.+decWordMore ::+  e -> -- Error message+  Word -> -- Accumulator+  Bytes -> -- Chunk+  Result# e Word#+decWordMore e !acc !chunk0 = case len of+  0 -> (# | (# unW (fromIntegral acc), unI (offset chunk0), 0# #) #)+  _ ->+    let !w =+          fromIntegral @Word8 @Word+            (PM.indexByteArray (array chunk0) (offset chunk0))+            - 48+     in if w < 10+          then+            let (overflow, acc') = unsignedPushBase10 acc w+             in if overflow+                  then (# e | #)+                  else decWordMore e acc' (Bytes.unsafeDrop 1 chunk0)+          else (# | (# unW (fromIntegral acc), unI (offset chunk0), len# #) #)+ where+  !len@(I# len#) = length chunk0++upcastWordResult :: Result# e Word# -> Result# e Word+{-# INLINE upcastWordResult #-}+upcastWordResult (# e | #) = (# e | #)+upcastWordResult (# | (# a, b, c #) #) = (# | (# W# a, b, c #) #)++{- FOURMOLU_DISABLE -}+-- This only works on 64-bit platforms.+upcastWord64Result :: Result# e Word# -> Result# e Word64+{-# inline upcastWord64Result #-}+upcastWord64Result (# e | #) = (# e | #)+upcastWord64Result (# | (# a, b, c #) #) = (# | (# W64# (+#if MIN_VERSION_base(4,17,0)+    Exts.wordToWord64# a+#else+    a+#endif+    ), b, c #) #)+{- FOURMOLU_ENABLE -}++hexSmallWordMore ::+  e -> -- Error message+  Word -> -- Accumulator+  Word -> -- Upper Bound+  Bytes -> -- Chunk+  Result# e Word#+hexSmallWordMore e !acc !limit !chunk0 =+  if length chunk0 > 0+    then case oneHexMaybe (PM.indexByteArray (array chunk0) (offset chunk0)) of+      Nothing -> (# | (# unW acc, unI (offset chunk0), unI (length chunk0) #) #)+      Just w ->+        let w' = acc * 16 + w+         in if w' < limit+              then hexSmallWordMore e w' limit (Bytes.unsafeDrop 1 chunk0)+              else (# e | #)+    else (# | (# unW acc, unI (offset chunk0), 0# #) #)++decSmallWordMore ::+  e -> -- Error message+  Word -> -- Accumulator+  Word -> -- Upper Bound+  Bytes -> -- Chunk+  Result# e Word#+decSmallWordMore e !acc !limit !chunk0 =+  if length chunk0 > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then+              let w' = acc * 10 + w+               in if w' < limit+                    then decSmallWordMore e w' limit (Bytes.unsafeDrop 1 chunk0)+                    else (# e | #)+            else (# | (# unW acc, unI (offset chunk0), unI (length chunk0) #) #)+    else (# | (# unW acc, unI (offset chunk0), 0# #) #)++unW :: Word -> Word#+{-# INLINE unW #-}+unW (W# w) = w++decWordStart ::+  e -> -- Error message+  Bytes -> -- Chunk+  ST# s (Result# e Word#)+decWordStart e !chunk0 s0 =+  if length chunk0 > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then (# s0, decWordMore e w (Bytes.unsafeDrop 1 chunk0) #)+            else (# s0, (# e | #) #)+    else (# s0, (# e | #) #)++{- FOURMOLU_DISABLE -}+-- Precondition: the word is small enough+upcastWord16Result :: Result# e Word# -> Result# e Word16+{-# inline upcastWord16Result #-}+upcastWord16Result (# e | #) = (# e | #)+upcastWord16Result (# | (# a, b, c #) #) = (# | (# W16# (+#if MIN_VERSION_base(4,16,0)+  Exts.wordToWord16#+#endif+  a), b, c #) #)++-- Precondition: the word is small enough+upcastWord32Result :: Result# e Word# -> Result# e Word32+{-# inline upcastWord32Result #-}+upcastWord32Result (# e | #) = (# e | #)+upcastWord32Result (# | (# a, b, c #) #) = (# | (# W32# (+#if MIN_VERSION_base(4,16,0)+  Exts.wordToWord32#+#endif+  a), b, c #) #)++-- Precondition: the word is small enough+upcastWord8Result :: Result# e Word# -> Result# e Word8+{-# inline upcastWord8Result #-}+upcastWord8Result (# e | #) = (# e | #)+upcastWord8Result (# | (# a, b, c #) #) = (# | (# W8# (+#if MIN_VERSION_base(4,16,0)+  Exts.wordToWord8#+#endif+  a), b, c #) #)+{- FOURMOLU_ENABLE -}++{- | Parse a decimal-encoded number. If the number is too large to be+represented by a machine integer, this fails with the provided+error message. This rejects input with that is preceeded by plus+or minus. Consequently, it does not parse negative numbers. Use+'decStandardInt' or 'decSignedInt' for that purpose. On a 64-bit+platform 'decWord' will successfully parse 9223372036854775808+(i.e. @2 ^ 63@), but 'decUnsignedInt' will fail. This parser allows+leading zeroes.+-}+decUnsignedInt :: e -> Parser e s Int+decUnsignedInt e =+  Parser+    ( \chunk0 s0 -> case decPosIntStart e (boxBytes chunk0) s0 of+        (# s1, r #) -> (# s1, upcastIntResult r #)+    )++-- | Variant of 'decUnsignedInt' with an unboxed result.+decUnsignedInt# :: e -> Parser e s Int#+decUnsignedInt# e =+  Parser+    (\chunk0 s0 -> decPosIntStart e (boxBytes chunk0) s0)++{- | Parse a decimal-encoded number. If the number is too large to be+represented by a machine integer, this fails with the provided+error message. This allows the number to optionally be prefixed+by plus or minus. If the sign prefix is not present, the number+is interpreted as positive. This allows leading zeroes.+-}+decSignedInt :: e -> Parser e s Int+decSignedInt e =+  Parser+    ( \chunk0 s0 -> case runParser (decSignedInt# e) chunk0 s0 of+        (# s1, r #) -> (# s1, upcastIntResult r #)+    )++{- | Variant of 'decUnsignedInt' that lets the caller supply a leading+digit. This is useful when parsing formats like JSON where integers with+leading zeroes are considered invalid. The calling context must+consume the first digit before calling this parser. Results are+always positive numbers.+-}+decTrailingInt ::+  -- | Error message+  e ->+  -- | Leading digit, should be between @0@ and @9@.+  Int ->+  Parser e s Int+decTrailingInt e (I# w) =+  Parser+    ( \chunk0 s0 -> case runParser (decTrailingInt# e w) chunk0 s0 of+        (# s1, r #) -> (# s1, upcastIntResult r #)+    )++decTrailingInt# ::+  e -> -- Error message+  Int# -> -- Leading digit, should be between @0@ and @9@.+  Parser e s Int#+decTrailingInt# e !w =+  Parser (\chunk0 s0 -> (# s0, decPosIntMore e (W# (int2Word# w)) maxIntAsWord (boxBytes chunk0) #))++maxIntAsWord :: Word+maxIntAsWord = fromIntegral (maxBound :: Int)++{- | Parse a decimal-encoded number. If the number is too large to be+represented by a machine integer, this fails with the provided+error message. This allows the number to optionally be prefixed+by minus. If the minus prefix is not present, the number+is interpreted as positive. The disallows a leading plus sign.+For example, 'decStandardInt' rejects @+42@, but 'decSignedInt'+allows it.+-}+decStandardInt :: e -> Parser e s Int+decStandardInt e =+  Parser+    ( \chunk0 s0 -> case runParser (decStandardInt# e) chunk0 s0 of+        (# s1, r #) -> (# s1, upcastIntResult r #)+    )++decSignedInt# :: e -> Parser e s Int#+{-# NOINLINE decSignedInt# #-}+decSignedInt# e =+  any e `bindFromLiftedToInt` \c -> case c of+    '+' ->+      Parser -- plus sign+        (\chunk0 s0 -> decPosIntStart e (boxBytes chunk0) s0)+    '-' ->+      Parser -- minus sign+        (\chunk0 s0 -> decNegIntStart e (boxBytes chunk0) s0)+    _ ->+      Parser -- no sign, there should be a digit here+        ( \chunk0 s0 ->+            let !w = char2Word c - 48+             in if w < 10+                  then (# s0, decPosIntMore e w maxIntAsWord (boxBytes chunk0) #)+                  else (# s0, (# e | #) #)+        )++-- This is the same as decSignedInt except that we disallow+-- a leading plus sign.+decStandardInt# :: e -> Parser e s Int#+{-# NOINLINE decStandardInt# #-}+decStandardInt# e =+  any e `bindFromLiftedToInt` \c -> case c of+    '-' ->+      Parser -- minus sign+        (\chunk0 s0 -> decNegIntStart e (boxBytes chunk0) s0)+    _ ->+      Parser -- no sign, there should be a digit here+        ( \chunk0 s0 ->+            let !w = char2Word c - 48+             in if w < 10+                  then (# s0, decPosIntMore e w maxIntAsWord (boxBytes chunk0) #)+                  else (# s0, (# e | #) #)+        )++{- | Variant of 'decUnsignedInteger' that lets the caller supply a leading+digit. This is useful when parsing formats like JSON where integers with+leading zeroes are considered invalid. The calling context must+consume the first digit before calling this parser. Results are+always positive numbers.+-}+decTrailingInteger ::+  -- | Leading digit, should be between @0@ and @9@.+  Int ->+  Parser e s Integer+decTrailingInteger (I# w) =+  Parser (\chunk0 s0 -> (# s0, (# | decIntegerChunks (I# w) 10 0 (boxBytes chunk0) #) #))++{- | Parse a decimal-encoded positive integer of arbitrary+size. This rejects input that begins with a plus or minus+sign.+-}+decUnsignedInteger :: e -> Parser e s Integer+decUnsignedInteger e =+  Parser+    (\chunk0 s0 -> decUnsignedIntegerStart e (boxBytes chunk0) s0)++{- | Parse a decimal-encoded integer of arbitrary size.+This accepts input that begins with a plus or minus sign.+Input without a sign prefix is interpreted as positive.+-}+decSignedInteger :: e -> Parser e s Integer+{-# NOINLINE decSignedInteger #-}+decSignedInteger e =+  any e >>= \c -> case c of+    '+' -> do+      decUnsignedInteger e+    '-' -> do+      x <- decUnsignedInteger e+      pure $! negate x+    _ ->+      Parser -- no sign, there should be a digit here+        ( \chunk0 s0 ->+            let !w = char2Word c - 48+             in if w < 10+                  then+                    let !r =+                          decIntegerChunks+                            (fromIntegral @Word @Int w)+                            10+                            0+                            (boxBytes chunk0)+                     in (# s0, (# | r #) #)+                  else (# s0, (# e | #) #)+        )++decPosIntStart ::+  e -> -- Error message+  Bytes -> -- Chunk+  ST# s (Result# e Int#)+decPosIntStart e !chunk0 s0 =+  if length chunk0 > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then (# s0, decPosIntMore e w maxIntAsWord (Bytes.unsafeDrop 1 chunk0) #)+            else (# s0, (# e | #) #)+    else (# s0, (# e | #) #)++decNegIntStart ::+  e -> -- Error message+  Bytes -> -- Chunk+  ST# s (Result# e Int#)+decNegIntStart e !chunk0 s0 =+  if length chunk0 > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then case decPosIntMore e w (maxIntAsWord + 1) (Bytes.unsafeDrop 1 chunk0) of+              (# | (# x, y, z #) #) ->+                (# s0, (# | (# (notI# x +# 1#), y, z #) #) #)+              (# err | #) ->+                (# s0, (# err | #) #)+            else (# s0, (# e | #) #)+    else (# s0, (# e | #) #)++decUnsignedIntegerStart ::+  e ->+  Bytes ->+  ST# s (Result# e Integer)+decUnsignedIntegerStart e !chunk0 s0 =+  if length chunk0 > 0+    then+      let !w = (PM.indexByteArray (array chunk0) (offset chunk0)) - 48+       in if w < (10 :: Word8)+            then+              let !r =+                    decIntegerChunks+                      (fromIntegral @Word8 @Int w)+                      10+                      0+                      (Bytes.unsafeDrop 1 chunk0)+               in (# s0, (# | r #) #)+            else (# s0, (# e | #) #)+    else (# s0, (# e | #) #)++-- This will not inline since it is recursive, but worker+-- wrapper will still happen. Fails if the accumulator+-- exceeds the upper bound.+decPosIntMore ::+  e -> -- Error message+  Word -> -- Accumulator, precondition: less than or equal to bound+  Word -> -- Inclusive Upper Bound, either (2^63 - 1) or 2^63+  Bytes -> -- Chunk+  Result# e Int#+decPosIntMore e !acc !upper !chunk0 =+  if len > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then+              let (overflow, acc') = positivePushBase10 acc w upper+               in if overflow+                    then (# e | #)+                    else decPosIntMore e acc' upper (Bytes.unsafeDrop 1 chunk0)+            else (# | (# unI (fromIntegral acc), unI (offset chunk0), len# #) #)+    else (# | (# unI (fromIntegral acc), unI (offset chunk0), 0# #) #)+ where+  !len@(I# len#) = length chunk0++-- This will not inline since it is recursive, but worker+-- wrapper will still happen. When the accumulator+-- exceeds the size of a machine integer, this pushes the+-- accumulated machine int and the shift amount onto the+-- stack.+-- We are intentionally lazy in the accumulator. There is+-- no need to force this on every iteration. We do however,+-- force it preemptively every time it changes.+-- Because of how we track overflow, we are able to use the+-- same function for both positive and negative numbers.+decIntegerChunks ::+  Int -> -- Chunk accumulator (e.g. 236)+  Int -> -- Chunk base-ten bound (e.g. 1000)+  Integer -> -- Accumulator+  Bytes -> -- Chunk+  (# Integer, Int#, Int# #)+decIntegerChunks !nAcc !eAcc acc !chunk0 =+  if len > 0+    then+      let !w =+            fromIntegral @Word8 @Word+              (PM.indexByteArray (array chunk0) (offset chunk0))+              - 48+       in if w < 10+            then+              let !eAcc' = eAcc * 10+               in if eAcc' >= eAcc+                    then+                      decIntegerChunks+                        (nAcc * 10 + fromIntegral @Word @Int w)+                        eAcc'+                        acc+                        (Bytes.unsafeDrop 1 chunk0)+                    else -- In this case, notice that we deliberately+                    -- unconsume the digit that would have caused+                    -- an overflow.++                      let !r =+                            (acc * fromIntegral @Int @Integer eAcc)+                              + (fromIntegral @Int @Integer nAcc)+                       in decIntegerChunks 0 1 r chunk0+            else+              let !r =+                    (acc * fromIntegral @Int @Integer eAcc)+                      + (fromIntegral @Int @Integer nAcc)+               in (# r, unI (offset chunk0), len# #)+    else+      let !r =+            (acc * fromIntegral @Int @Integer eAcc)+              + (fromIntegral @Int @Integer nAcc)+       in (# r, unI (offset chunk0), 0# #)+ where+  !len@(I# len#) = length chunk0++upcastIntResult :: Result# e Int# -> Result# e Int+upcastIntResult (# e | #) = (# e | #)+upcastIntResult (# | (# a, b, c #) #) = (# | (# I# a, b, c #) #)++char2Word :: Char -> Word+char2Word = fromIntegral . ord++{- | Take characters until the specified character is encountered.+Consumes the matched character as well. Fails if the character+is not present.  Visually, the cursor advancement and resulting+@Bytes@ for @takeTrailedBy \'D\'@ look like this:++>  A B C D E F | input+> |->->->-|    | cursor+> {\-*-*-\}      | result bytes+-}+takeTrailedBy :: e -> Char -> Parser e s Bytes+takeTrailedBy e !w = do+  !start <- cursor+  skipTrailedBy e w+  !end <- cursor+  !arr <- expose+  pure (Bytes arr start (end - (start + 1)))++{- | Skip all characters until the terminator is encountered+and then consume the matching character as well. Visually,+@skipTrailedBy \'C\'@ advances the cursor like this:++>  A Z B Y C X C W+> |->->->->-|++This fails if it reaches the end of input without encountering+the character.+-}+skipTrailedBy :: e -> Char -> Parser e s ()+skipTrailedBy e !w = uneffectful# $ \c ->+  skipUntilConsumeLoop e w c++{- | Skip all characters until the terminator is encountered.+This does not consume the terminator. Visually, @skipUntil \'C\'@+advances the cursor like this:++>  A Z B Y C X C W+> |->->->-|++This succeeds if it reaches the end of the input without+encountering the terminator. It never fails.+-}+skipUntil :: Char -> Parser e s ()+skipUntil !w = uneffectful# $ \c -> skipUntilLoop w c++skipUntilLoop ::+  Char -> -- byte to match+  Bytes -> -- Chunk+  Result# e ()+skipUntilLoop !w !c = case length c of+  0 -> (# | (# (), unI (offset c), 0# #) #)+  _ ->+    if indexLatinCharArray (array c) (offset c) /= w+      then skipUntilLoop w (Bytes.unsafeDrop 1 c)+      else (# | (# (), unI (offset c), unI (length c) #) #)++skipUntilConsumeLoop ::+  e -> -- Error message+  Char -> -- byte to match+  Bytes -> -- Chunk+  Result# e ()+skipUntilConsumeLoop e !w !c = case length c of+  0 -> (# e | #)+  _ ->+    if indexLatinCharArray (array c) (offset c) /= w+      then skipUntilConsumeLoop e w (Bytes.unsafeDrop 1 c)+      else (# | (# (), unI (offset c + 1), unI (length c - 1) #) #)++{- FOURMOLU_DISABLE -}+-- | Parse exactly eight ASCII-encoded characters, interpreting them as the+-- hexadecimal encoding of a 32-bit number. Note that this rejects a sequence+-- such as @BC5A9@, requiring @000BC5A9@ instead. This is insensitive to case.+hexFixedWord32 :: e -> Parser e s Word32+{-# inline hexFixedWord32 #-}+hexFixedWord32 e = Parser+  (\x s0 -> case runParser (hexFixedWord32# e) x s0 of+    (# s1, r #) -> case r of+      (# err | #) -> (# s1, (# err | #) #)+      (# | (# a, b, c #) #) -> (# s1, (# | (# W32# (+#if MIN_VERSION_base(4,16,0)+        Exts.wordToWord32#+#endif+        a), b, c #) #) #)+  )+{- FOURMOLU_ENABLE -}++hexFixedWord32# :: e -> Parser e s Word#+{-# NOINLINE hexFixedWord32# #-}+hexFixedWord32# e = uneffectfulWord# $ \chunk ->+  if length chunk >= 8+    then+      let !w0@(W# n0) = oneHex $ PM.indexByteArray (array chunk) (offset chunk)+          !w1@(W# n1) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 1)+          !w2@(W# n2) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 2)+          !w3@(W# n3) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 3)+          !w4@(W# n4) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 4)+          !w5@(W# n5) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 5)+          !w6@(W# n6) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 6)+          !w7@(W# n7) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 7)+       in if+            | w0 .|. w1 .|. w2 .|. w3 .|. w4 .|. w5 .|. w6 .|. w7 /= maxBound ->+                (#+                  | (#+                      (n0 `Exts.timesWord#` 268435456##)+                        `Exts.plusWord#` (n1 `Exts.timesWord#` 16777216##)+                        `Exts.plusWord#` (n2 `Exts.timesWord#` 1048576##)+                        `Exts.plusWord#` (n3 `Exts.timesWord#` 65536##)+                        `Exts.plusWord#` (n4 `Exts.timesWord#` 4096##)+                        `Exts.plusWord#` (n5 `Exts.timesWord#` 256##)+                        `Exts.plusWord#` (n6 `Exts.timesWord#` 16##)+                        `Exts.plusWord#` n7+                      , unI (offset chunk) +# 8#+                      , unI (length chunk) -# 8#+                    #)+                #)+            | otherwise -> (# e | #)+    else (# e | #)++{- FOURMOLU_DISABLE -}+-- | Parse exactly 16 ASCII-encoded characters, interpreting them as the+-- hexadecimal encoding of a 64-bit number. Note that this rejects a sequence+-- such as @BC5A9@, requiring @00000000000BC5A9@ instead. This is insensitive+-- to case.+hexFixedWord64 :: e -> Parser e s Word64+{-# inline hexFixedWord64 #-}+hexFixedWord64 e = Parser+  (\x s0 -> case runParser (hexFixedWord64# e) x s0 of+    (# s1, r #) -> case r of+      (# err | #) -> (# s1, (# err | #) #)+      (# | (# a, b, c #) #) -> (# s1, (# | (# W64# (+#if MIN_VERSION_base(4,17,0)+          Exts.wordToWord64# a+#else++          a+#endif+          ), b, c #) #) #)+  )+{- FOURMOLU_ENABLE -}++hexFixedWord128 :: e -> Parser e s Word128+hexFixedWord128 e =+  Word128+    <$> hexFixedWord64 e+    <*> hexFixedWord64 e++hexFixedWord256 :: e -> Parser e s Word256+hexFixedWord256 e =+  Word256+    <$> hexFixedWord64 e+    <*> hexFixedWord64 e+    <*> hexFixedWord64 e+    <*> hexFixedWord64 e++hexFixedWord64# :: e -> Parser e s Word#+{-# NOINLINE hexFixedWord64# #-}+hexFixedWord64# e = uneffectfulWord# $ \chunk ->+  if length chunk >= 16+    then+      let go !off !len !acc = case len of+            0 -> case acc of+              W# r ->+                (#+                  | (#+                      r+                      , unI off+                      , unI (length chunk) -# 16#+                    #)+                #)+            _ -> case oneHexMaybe (PM.indexByteArray (array chunk) off) of+              Nothing -> (# e | #)+              Just w -> go (off + 1) (len - 1) ((acc * 16) + w)+       in go (offset chunk) (16 :: Int) (0 :: Word)+    else (# e | #)++{- FOURMOLU_DISABLE -}+-- | Parse exactly four ASCII-encoded characters, interpreting+-- them as the hexadecimal encoding of a 16-bit number. Note that+-- this rejects a sequence such as @5A9@, requiring @05A9@ instead.+-- This is insensitive to case. This is particularly useful when+-- parsing escape sequences in C or JSON, which allow encoding+-- characters in the Basic Multilingual Plane as @\\uhhhh@.+hexFixedWord16 :: e -> Parser e s Word16+{-# inline hexFixedWord16 #-}+hexFixedWord16 e = Parser+  (\x s0 -> case runParser (hexFixedWord16# e) x s0 of+    (# s1, r #) -> case r of+      (# err | #) -> (# s1, (# err | #) #)+      (# | (# a, b, c #) #) -> (# s1, (# | (# W16# (+#if MIN_VERSION_base(4,16,0)+        Exts.wordToWord16#+#endif+        a), b, c #) #) #)+  )++hexFixedWord16# :: e -> Parser e s Word#+{-# noinline hexFixedWord16# #-}+hexFixedWord16# e = uneffectfulWord# $ \chunk -> if length chunk >= 4+  then+    let !w0@(W# n0) = oneHex $ PM.indexByteArray (array chunk) (offset chunk)+        !w1@(W# n1) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 1)+        !w2@(W# n2) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 2)+        !w3@(W# n3) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 3)+     in if | w0 .|. w1 .|. w2 .|. w3 /= maxBound ->+             (# |+                (# (n0 `Exts.timesWord#` 4096##) `Exts.plusWord#`+                   (n1 `Exts.timesWord#` 256##) `Exts.plusWord#`+                   (n2 `Exts.timesWord#` 16##) `Exts.plusWord#`+                   n3+                ,  unI (offset chunk) +# 4#+                ,  unI (length chunk) -# 4# #) #)+           | otherwise -> (# e | #)+  else (# e | #)++-- | Parse exactly two ASCII-encoded characters, interpretting+-- them as the hexadecimal encoding of a 8-bit number. Note that+-- this rejects a sequence such as @A@, requiring @0A@ instead.+-- This is insensitive to case.+hexFixedWord8 :: e -> Parser e s Word8+{-# inline hexFixedWord8 #-}+hexFixedWord8 e = Parser+  (\x s0 -> case runParser (hexFixedWord8# e) x s0 of+    (# s1, r #) -> case r of+      (# err | #) -> (# s1, (# err | #) #)+      (# | (# a, b, c #) #) -> (# s1, (# | (# W8# (+#if MIN_VERSION_base(4,16,0)+        Exts.wordToWord8#+#endif+        a), b, c #) #) #)+  )+{- FOURMOLU_ENABLE -}++hexFixedWord8# :: e -> Parser e s Word#+{-# NOINLINE hexFixedWord8# #-}+hexFixedWord8# e = uneffectfulWord# $ \chunk ->+  if length chunk >= 2+    then+      let !w0@(W# n0) = oneHex $ PM.indexByteArray (array chunk) (offset chunk)+          !w1@(W# n1) = oneHex $ PM.indexByteArray (array chunk) (offset chunk + 1)+       in if+            | w0 .|. w1 /= maxBound ->+                (#+                  | (#+                      (n0 `Exts.timesWord#` 16##)+                        `Exts.plusWord#` n1+                      , unI (offset chunk) +# 2#+                      , unI (length chunk) -# 2#+                    #)+                #)+            | otherwise -> (# e | #)+    else (# e | #)++{- | Consume a single character that is the lowercase hexadecimal+encoding of a 4-bit word. Fails if the character is not in the class+@[a-f0-9]@.+-}+hexNibbleLower :: e -> Parser e s Word+hexNibbleLower e = uneffectful $ \chunk -> case length chunk of+  0 -> Failure e+  _ ->+    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+     in if+          | w >= 48 && w < 58 -> Success (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)+          | w >= 97 && w < 103 -> Success (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)+          | otherwise -> Failure e++{- | Consume a single character that is the case-insensitive hexadecimal+encoding of a 4-bit word. Fails if the character is not in the class+@[a-fA-F0-9]@.+-}+hexNibble :: e -> Parser e s Word+hexNibble e = uneffectful $ \chunk -> case length chunk of+  0 -> Failure e+  _ ->+    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+     in if+          | w >= 48 && w < 58 -> Success (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)+          | w >= 65 && w < 71 -> Success (fromIntegral w - 55) (offset chunk + 1) (length chunk - 1)+          | w >= 97 && w < 103 -> Success (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)+          | otherwise -> Failure e++{- | Consume a single character that is the lowercase hexadecimal+encoding of a 4-bit word. Returns @Nothing@ without consuming+the character if it is not in the class @[a-f0-9]@. The parser+never fails.+-}+tryHexNibbleLower :: Parser e s (Maybe Word)+tryHexNibbleLower = unfailing $ \chunk -> case length chunk of+  0 -> InternalStep Nothing (offset chunk) (length chunk)+  _ ->+    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+     in if+          | w >= 48 && w < 58 -> InternalStep (Just (fromIntegral w - 48)) (offset chunk + 1) (length chunk - 1)+          | w >= 97 && w < 103 -> InternalStep (Just (fromIntegral w - 87)) (offset chunk + 1) (length chunk - 1)+          | otherwise -> InternalStep Nothing (offset chunk) (length chunk)++{- | Consume a single character that is the case-insensitive hexadecimal+encoding of a 4-bit word. Returns @Nothing@ without consuming+the character if it is not in the class @[a-fA-F0-9]@. This parser+never fails.+-}+tryHexNibble :: Parser e s (Maybe Word)+tryHexNibble = unfailing $ \chunk -> case length chunk of+  0 -> InternalStep Nothing (offset chunk) (length chunk)+  _ ->+    let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8+     in if+          | w >= 48 && w < 58 -> InternalStep (Just (fromIntegral w - 48)) (offset chunk + 1) (length chunk - 1)+          | w >= 65 && w < 71 -> InternalStep (Just (fromIntegral w - 55)) (offset chunk + 1) (length chunk - 1)+          | w >= 97 && w < 103 -> InternalStep (Just (fromIntegral w - 87)) (offset chunk + 1) (length chunk - 1)+          | otherwise -> InternalStep Nothing (offset chunk) (length chunk)++-- Returns the maximum machine word if the argument is not+-- the ASCII encoding of a hexadecimal digit.+oneHex :: Word8 -> Word+{-# INLINE oneHex #-}+oneHex w+  | w >= 48 && w < 58 = (fromIntegral w - 48)+  | w >= 65 && w < 71 = (fromIntegral w - 55)+  | w >= 97 && w < 103 = (fromIntegral w - 87)+  | otherwise = maxBound++oneHexMaybe :: Word8 -> Maybe Word+{-# INLINE oneHexMaybe #-}+oneHexMaybe w+  | w >= 48 && w < 58 = Just (fromIntegral w - 48)+  | w >= 65 && w < 71 = Just (fromIntegral w - 55)+  | w >= 97 && w < 103 = Just (fromIntegral w - 87)+  | otherwise = Nothing++uneffectfulWord# :: (Bytes -> Result# e Word#) -> Parser e s Word#+{-# INLINE uneffectfulWord# #-}+uneffectfulWord# f =+  Parser+    (\b s0 -> (# s0, (f (boxBytes b)) #))++-- Precondition: the arguments are non-negative. Boolean is+-- true when overflow happens. Performs: a * 10 + b+-- Postcondition: when overflow is false, the resulting+-- word is less than or equal to the upper bound+positivePushBase10 :: Word -> Word -> Word -> (Bool, Word)+{-# INLINE positivePushBase10 #-}+positivePushBase10 (W# a) (W# b) (W# upper) =+  let !(# ca, r0 #) = Exts.timesWord2# a 10##+      !r1 = Exts.plusWord# r0 b+      !cb = int2Word# (gtWord# r1 upper)+      !cc = int2Word# (ltWord# r1 0##)+      !c = ca `or#` cb `or#` cc+   in (case c of 0## -> False; _ -> True, W# r1)++unsignedPushBase10 :: Word -> Word -> (Bool, Word)+{-# INLINE unsignedPushBase10 #-}+unsignedPushBase10 (W# a) (W# b) =+  let !(# ca, r0 #) = Exts.timesWord2# a 10##+      !r1 = Exts.plusWord# r0 b+      !cb = int2Word# (ltWord# r1 r0)+      !c = ca `or#` cb+   in (case c of 0## -> False; _ -> True, W# r1)++-- | Skip while the predicate is matched. This is always inlined.+skipWhile :: (Char -> Bool) -> Parser e s ()+{-# INLINE skipWhile #-}+skipWhile f = go+ where+  go =+    isEndOfInput >>= \case+      True -> pure ()+      False -> do+        w <- anyUnsafe+        if f w+          then go+          else unconsume 1++-- Interpret the next byte as an Latin1-encoded character.+-- Does not check to see if any characters are left. This+-- is not exported.+anyUnsafe :: Parser e s Char+{-# INLINE anyUnsafe #-}+anyUnsafe = uneffectful $ \chunk ->+  let w = indexCharArray (array chunk) (offset chunk) :: Char+   in Success w (offset chunk + 1) (length chunk - 1)++-- Reads one byte and interprets it as Latin1-encoded character.+indexCharArray :: PM.ByteArray -> Int -> Char+{-# INLINE indexCharArray #-}+indexCharArray (PM.ByteArray x) (I# i) = C# (indexCharArray# x i)++{- | Match any character, to perform lookahead. Returns 'Nothing' if+  end of input has been reached. Does not consume any input.++  /Note/: Because this parser does not fail, do not use it+  with combinators such as 'many', because such as 'many',+  because such parsers loop until a failure occurs. Careless+  use will thus result in an infinite loop.+-}+peek :: Parser e s (Maybe Char)+{-# INLINE peek #-}+peek = uneffectful $ \(Bytes arr off len) ->+  let v =+        if len > 0+          then Just (indexCharArray arr off)+          else Nothing+   in Success v off len++{- | Match any byte, to perform lookahead. Does not consume any+  input, but will fail if end of input has been reached.+-}+peek' :: e -> Parser e s Char+{-# INLINE peek' #-}+peek' e = uneffectful $ \(Bytes arr off len) ->+  if len > 0+    then Success (indexCharArray arr off) off len+    else Failure e
src/Data/Bytes/Parser/Leb128.hs view
@@ -1,66 +1,73 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language TypeApplications #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE TypeApplications #-} --- | Parse numbers that have been encoded with <https://en.wikipedia.org/wiki/LEB128 LEB-128>.--- LEB-128 allows arbitrarily large numbers to be encoded. Parsers in this--- module will fail if the number they attempt to parse is outside the--- range of what their target type can handle. The parsers for signed--- numbers assume that the numbers have been--- <https://developers.google.com/protocol-buffers/docs/encoding zigzig encoded>.+{- | Parse numbers that have been encoded with <https://en.wikipedia.org/wiki/LEB128 LEB-128>.+LEB-128 allows arbitrarily large numbers to be encoded. Parsers in this+module will fail if the number they attempt to parse is outside the+range of what their target type can handle. The parsers for signed+numbers assume that the numbers have been+<https://developers.google.com/protocol-buffers/docs/encoding zigzig encoded>.+-} module Data.Bytes.Parser.Leb128   ( -- * Unsigned     word16   , word32   , word64+     -- * Signed (Zig-zag)   , int16   , int32   , int64   ) where -import Data.Bits (testBit,(.&.),unsafeShiftR,xor,complement)-import Data.Bits (unsafeShiftL,(.|.))+import Data.Bits (complement, testBit, unsafeShiftL, unsafeShiftR, xor, (.&.), (.|.)) import Data.Bytes.Parser (Parser)-import Data.Int (Int16,Int32,Int64)-import Data.Word (Word8,Word16,Word32,Word64)+import Data.Int (Int16, Int32, Int64)+import Data.Word (Word16, Word32, Word64, Word8)  import qualified Data.Bytes.Parser as P --- | Parse a LEB-128-encoded number. If the number is larger--- than @0xFFFF@, fails with the provided error.+{- | Parse a LEB-128-encoded number. If the number is larger+than @0xFFFF@, fails with the provided error.+-} word16 :: e -> Parser e s Word16 word16 e = do   w <- stepBoundedWord e 16 0 0   pure (fromIntegral @Word64 @Word16 w) --- | Parse a LEB-128-encoded number. If the number is larger--- than @0xFFFFFFFF@, fails with the provided error.+{- | Parse a LEB-128-encoded number. If the number is larger+than @0xFFFFFFFF@, fails with the provided error.+-} word32 :: e -> Parser e s Word32 word32 e = do   w <- stepBoundedWord e 32 0 0   pure (fromIntegral @Word64 @Word32 w) --- | Parse a LEB-128-encoded number. If the number is larger--- than @0xFFFFFFFFFFFFFFFF@, fails with the provided error.+{- | Parse a LEB-128-encoded number. If the number is larger+than @0xFFFFFFFFFFFFFFFF@, fails with the provided error.+-} word64 :: e -> Parser e s Word64 word64 e = stepBoundedWord e 64 0 0 --- | Parse a LEB-128-zigzag-encoded signed number. If the encoded--- number is outside the range @[-32768,32767]@, this fails with--- the provided error.+{- | Parse a LEB-128-zigzag-encoded signed number. If the encoded+number is outside the range @[-32768,32767]@, this fails with+the provided error.+-} int16 :: e -> Parser e s Int16 int16 = fmap zigzagDecode16 . word16 --- | Parse a LEB-128-zigzag-encoded signed number. If the encoded--- number is outside the range @[-2147483648,2147483647]@, this--- fails with the provided error.+{- | Parse a LEB-128-zigzag-encoded signed number. If the encoded+number is outside the range @[-2147483648,2147483647]@, this+fails with the provided error.+-} int32 :: e -> Parser e s Int32 int32 = fmap zigzagDecode32 . word32 --- | Parse a LEB-128-zigzag-encoded signed number. If the encoded--- number is outside the range @[-9223372036854775808,9223372036854775807]@,--- this fails with the provided error.+{- | Parse a LEB-128-zigzag-encoded signed number. If the encoded+number is outside the range @[-9223372036854775808,9223372036854775807]@,+this fails with the provided error.+-} int64 :: e -> Parser e s Int64 int64 = fmap zigzagDecode64 . word64 @@ -72,16 +79,19 @@ stepBoundedWord e !bitLimit !acc0 !accShift = do   raw <- P.any e   let number = raw .&. 0x7F-      acc1 = acc0 .|.-        unsafeShiftL (fromIntegral @Word8 @Word64 number) accShift+      acc1 =+        acc0+          .|. unsafeShiftL (fromIntegral @Word8 @Word64 number) accShift       accShift' = accShift + 7   if accShift' <= bitLimit-    then if testBit raw 7-      then stepBoundedWord e bitLimit acc1 accShift'-      else pure acc1-    else if fromIntegral @Word8 @Word raw < twoExp (bitLimit - accShift)-      then pure acc1 -- TODO: no need to mask upper bit in number-      else P.fail e+    then+      if testBit raw 7+        then stepBoundedWord e bitLimit acc1 accShift'+        else pure acc1+    else+      if fromIntegral @Word8 @Word raw < twoExp (bitLimit - accShift)+        then pure acc1 -- TODO: no need to mask upper bit in number+        else P.fail e  twoExp :: Int -> Word twoExp x = unsafeShiftL 1 x
src/Data/Bytes/Parser/LittleEndian.hs view
@@ -1,24 +1,19 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UnboxedSums #-}  -- | Little-endian fixed-width numbers. module Data.Bytes.Parser.LittleEndian   ( -- * One+     -- ** Unsigned     word8   , word16@@ -26,36 +21,40 @@   , word64   , word128   , word256+     -- ** Signed   , int8   , int16   , int32   , int64+     -- * Many+     -- ** Unsigned   , word16Array   , word32Array   , word64Array   , word128Array   , word256Array+     -- ** Unsigned   , int64Array   ) where -import Prelude hiding (length,any,fail,takeWhile)+import Prelude hiding (any, fail, length, takeWhile) +#if MIN_VERSION_base(4,18,0)+#else import Control.Applicative (liftA2)-import Data.Bits ((.|.),unsafeShiftL)-import Data.Primitive (ByteArray(..),PrimArray(..))-import Data.Bytes.Types (Bytes(..))-import Data.Bytes.Parser.Internal (Parser,uneffectful)-import Data.Bytes.Parser.Internal (Result(..))-import Data.Bytes.Parser.Internal (swapArray16,swapArray32)-import Data.Bytes.Parser.Internal (swapArray64,swapArray128,swapArray256)-import Data.Word (Word8,Word16,Word32,Word64)-import Data.Int (Int8,Int16,Int32,Int64)-import Data.WideWord (Word128(Word128),Word256(Word256))-import GHC.ByteOrder (ByteOrder(LittleEndian,BigEndian),targetByteOrder)+#endif+import Data.Bits (unsafeShiftL, (.|.))+import Data.Bytes.Parser.Internal (Parser, Result (..), swapArray128, swapArray16, swapArray256, swapArray32, swapArray64, uneffectful)+import Data.Bytes.Types (Bytes (..))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Primitive (ByteArray (..), PrimArray (..))+import Data.WideWord (Word128 (Word128), Word256 (Word256))+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.ByteOrder (ByteOrder (BigEndian, LittleEndian), targetByteOrder)  import qualified Data.Bytes as Bytes import qualified Data.Bytes.Parser as P@@ -65,14 +64,18 @@ word8 :: e -> Parser e s Word8 word8 = P.any --- | Array of little-endian unsigned 16-bit words. If the host is--- little-endian, the implementation is optimized to simply @memcpy@--- bytes into the result array. The result array always has elements--- in native-endian byte order.+{- | Array of little-endian unsigned 16-bit words. If the host is+little-endian, the implementation is optimized to simply @memcpy@+bytes into the result array. The result array always has elements+in native-endian byte order.+-} word16Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of little-endian 16-bit words to expect-  -> Parser e s (PrimArray Word16) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of little-endian 16-bit words to expect+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word16) word16Array e !n = case targetByteOrder of   LittleEndian -> fmap (asWord16s . Bytes.toByteArrayClone) (P.take e (n * 2))   BigEndian -> do@@ -82,9 +85,12 @@  -- | Parse an array of little-endian unsigned 32-bit words. word32Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of little-endian 32-bit words to consume-  -> Parser e s (PrimArray Word32) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of little-endian 32-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word32) word32Array e !n = case targetByteOrder of   LittleEndian -> fmap (asWord32s . Bytes.toByteArrayClone) (P.take e (n * 4))   BigEndian -> do@@ -94,9 +100,12 @@  -- | Parse an array of little-endian unsigned 64-bit words. word64Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of little-endian 64-bit words to consume-  -> Parser e s (PrimArray Word64) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of little-endian 64-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word64) word64Array e !n = case targetByteOrder of   LittleEndian -> fmap (asWord64s . Bytes.toByteArrayClone) (P.take e (n * 8))   BigEndian -> do@@ -106,9 +115,12 @@  -- | Parse an array of little-endian unsigned 128-bit words. word128Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of little-endian 128-bit words to consume-  -> Parser e s (PrimArray Word128) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of little-endian 128-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word128) word128Array e !n = case targetByteOrder of   LittleEndian -> fmap (asWord128s . Bytes.toByteArrayClone) (P.take e (n * 16))   BigEndian -> do@@ -118,9 +130,12 @@  -- | Parse an array of little-endian unsigned 256-bit words. word256Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of little-endian 256-bit words to consume-  -> Parser e s (PrimArray Word256) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of little-endian 256-bit words to consume+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Word256) word256Array e !n = case targetByteOrder of   LittleEndian -> fmap (asWord256s . Bytes.toByteArrayClone) (P.take e (n * 32))   BigEndian -> do@@ -130,9 +145,12 @@  -- | Parse an array of little-endian signed 64-bit words. int64Array ::-     e -- ^ Error message if not enough bytes are present-  -> Int -- ^ Number of little-endian 64-bit words to expect-  -> Parser e s (PrimArray Int64) -- ^ Native-endian elements+  -- | Error message if not enough bytes are present+  e ->+  -- | Number of little-endian 64-bit words to expect+  Int ->+  -- | Native-endian elements+  Parser e s (PrimArray Int64) int64Array e !n = do   PrimArray x <- word64Array e n   pure (PrimArray x)@@ -154,58 +172,64 @@  -- | Unsigned 16-bit word. word16 :: e -> Parser e s Word16-word16 e = uneffectful $ \chunk -> if length chunk >= 2-  then-    let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8-        wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-     in Success-          (fromIntegral @Word @Word16 (unsafeShiftL (fromIntegral wb) 8 .|. fromIntegral wa))-          (offset chunk + 2) (length chunk - 2)-  else Failure e+word16 e = uneffectful $ \chunk ->+  if length chunk >= 2+    then+      let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8+          wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8+       in Success+            (fromIntegral @Word @Word16 (unsafeShiftL (fromIntegral wb) 8 .|. fromIntegral wa))+            (offset chunk + 2)+            (length chunk - 2)+    else Failure e  -- | Unsigned 32-bit word. word32 :: e -> Parser e s Word32-word32 e = uneffectful $ \chunk -> if length chunk >= 4-  then-    let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8-        wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-        wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8-        wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8-     in Success-          (fromIntegral @Word @Word32-            ( unsafeShiftL (fromIntegral wd) 24 .|.-              unsafeShiftL (fromIntegral wc) 16 .|.-              unsafeShiftL (fromIntegral wb) 8 .|.-              fromIntegral wa+word32 e = uneffectful $ \chunk ->+  if length chunk >= 4+    then+      let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8+          wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8+          wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8+          wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8+       in Success+            ( fromIntegral @Word @Word32+                ( unsafeShiftL (fromIntegral wd) 24+                    .|. unsafeShiftL (fromIntegral wc) 16+                    .|. unsafeShiftL (fromIntegral wb) 8+                    .|. fromIntegral wa+                )             )-          )-          (offset chunk + 4) (length chunk - 4)-  else Failure e+            (offset chunk + 4)+            (length chunk - 4)+    else Failure e  -- | Unsigned 64-bit word. word64 :: e -> Parser e s Word64-word64 e = uneffectful $ \chunk -> if length chunk >= 8-  then-    let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8-        wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-        wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8-        wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8-        we = PM.indexByteArray (array chunk) (offset chunk + 4) :: Word8-        wf = PM.indexByteArray (array chunk) (offset chunk + 5) :: Word8-        wg = PM.indexByteArray (array chunk) (offset chunk + 6) :: Word8-        wh = PM.indexByteArray (array chunk) (offset chunk + 7) :: Word8-     in Success-          ( unsafeShiftL (fromIntegral wh) 56 .|.-            unsafeShiftL (fromIntegral wg) 48 .|.-            unsafeShiftL (fromIntegral wf) 40 .|.-            unsafeShiftL (fromIntegral we) 32 .|.-            unsafeShiftL (fromIntegral wd) 24 .|.-            unsafeShiftL (fromIntegral wc) 16 .|.-            unsafeShiftL (fromIntegral wb) 8 .|.-            fromIntegral wa-          )-          (offset chunk + 8) (length chunk - 8)-  else Failure e+word64 e = uneffectful $ \chunk ->+  if length chunk >= 8+    then+      let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8+          wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8+          wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8+          wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8+          we = PM.indexByteArray (array chunk) (offset chunk + 4) :: Word8+          wf = PM.indexByteArray (array chunk) (offset chunk + 5) :: Word8+          wg = PM.indexByteArray (array chunk) (offset chunk + 6) :: Word8+          wh = PM.indexByteArray (array chunk) (offset chunk + 7) :: Word8+       in Success+            ( unsafeShiftL (fromIntegral wh) 56+                .|. unsafeShiftL (fromIntegral wg) 48+                .|. unsafeShiftL (fromIntegral wf) 40+                .|. unsafeShiftL (fromIntegral we) 32+                .|. unsafeShiftL (fromIntegral wd) 24+                .|. unsafeShiftL (fromIntegral wc) 16+                .|. unsafeShiftL (fromIntegral wb) 8+                .|. fromIntegral wa+            )+            (offset chunk + 8)+            (length chunk - 8)+    else Failure e  -- | Unsigned 256-bit word. word256 :: e -> Parser e s Word256
src/Data/Bytes/Parser/Rebindable.hs view
@@ -1,31 +1,30 @@-{-# language CPP #-}-{-# language DataKinds #-}-{-# language FlexibleInstances #-}-{-# language MagicHash #-}-{-# language MultiParamTypeClasses #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UnboxedTuples #-} --- | Provides levity-polymorphic variants of @>>=@, @>>@, and @pure@--- used to assemble parsers whose result types are unlifted. This--- cannot be used with the @RebindableSyntax@ extension because that--- extension disallows representations other than @LiftedRep@. Consequently,--- users of this module must manually desugar do notation. See the--- @url-bytes@ library for an example of this module in action.------ Only resort to the functions in this module after checking that--- GHC is unable to optimize away @I#@ and friends in your code.+{- | Provides levity-polymorphic variants of @>>=@, @>>@, and @pure@+used to assemble parsers whose result types are unlifted. This+cannot be used with the @RebindableSyntax@ extension because that+extension disallows representations other than @LiftedRep@. Consequently,+users of this module must manually desugar do notation. See the+@url-bytes@ library for an example of this module in action.++Only resort to the functions in this module after checking that+GHC is unable to optimize away @I#@ and friends in your code.+-} module Data.Bytes.Parser.Rebindable-  ( Bind(..)-  , Pure(..)+  ( Bind (..)+  , Pure (..)   ) where +import Data.Bytes.Parser.Internal (Parser (..))+import GHC.Exts (RuntimeRep (..), TYPE) import Prelude ()-import GHC.Exts (TYPE,RuntimeRep(..))-import Data.Bytes.Parser.Internal (Parser(..))  #if MIN_VERSION_base(4,16,0) import GHC.Exts (LiftedRep)@@ -34,411 +33,506 @@ #endif  class Bind (ra :: RuntimeRep) (rb :: RuntimeRep) where-  (>>=) :: forall e s (a :: TYPE ra) (b :: TYPE rb).-    Parser e s a -> (a -> Parser e s b) -> Parser e s b-  (>>) :: forall e s (a :: TYPE ra) (b :: TYPE rb).-    Parser e s a -> Parser e s b -> Parser e s b+  (>>=) ::+    forall e s (a :: TYPE ra) (b :: TYPE rb).+    Parser e s a ->+    (a -> Parser e s b) ->+    Parser e s b+  (>>) ::+    forall e s (a :: TYPE ra) (b :: TYPE rb).+    Parser e s a ->+    Parser e s b ->+    Parser e s b  class Pure (ra :: RuntimeRep) where   pure :: forall e s (a :: TYPE ra). a -> Parser e s a  pureParser :: a -> Parser e s a-{-# inline pureParser #-}-pureParser a = Parser-  (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))+{-# INLINE pureParser #-}+pureParser a =+  Parser+    (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))  bindParser :: Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindParser #-}-bindParser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+{-# INLINE bindParser #-}+bindParser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  sequenceParser :: Parser e s a -> Parser e s b -> Parser e s b-{-# inline sequenceParser #-}-sequenceParser (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+{-# INLINE sequenceParser #-}+sequenceParser (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    ) -pureIntParser :: forall (a :: TYPE 'IntRep) e s.-  a -> Parser e s a-{-# inline pureIntParser #-}-pureIntParser a = Parser-  (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))+pureIntParser ::+  forall (a :: TYPE 'IntRep) e s.+  a ->+  Parser e s a+{-# INLINE pureIntParser #-}+pureIntParser a =+  Parser+    (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #)) -bindIntParser :: forall (a :: TYPE 'IntRep) e s b.-  Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindIntParser #-}-bindIntParser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+bindIntParser ::+  forall (a :: TYPE 'IntRep) e s b.+  Parser e s a ->+  (a -> Parser e s b) ->+  Parser e s b+{-# INLINE bindIntParser #-}+bindIntParser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    ) -bindWordParser :: forall (a :: TYPE 'WordRep) e s b.-  Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindWordParser #-}-bindWordParser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+bindWordParser ::+  forall (a :: TYPE 'WordRep) e s b.+  Parser e s a ->+  (a -> Parser e s b) ->+  Parser e s b+{-# INLINE bindWordParser #-}+bindWordParser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    ) -sequenceIntParser :: forall (a :: TYPE 'IntRep) e s b.-  Parser e s a -> Parser e s b -> Parser e s b-{-# inline sequenceIntParser #-}-sequenceIntParser (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+sequenceIntParser ::+  forall (a :: TYPE 'IntRep) e s b.+  Parser e s a ->+  Parser e s b ->+  Parser e s b+{-# INLINE sequenceIntParser #-}+sequenceIntParser (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    ) -sequenceWordParser :: forall (a :: TYPE 'WordRep) e s b.-  Parser e s a -> Parser e s b -> Parser e s b-{-# inline sequenceWordParser #-}-sequenceWordParser (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+sequenceWordParser ::+  forall (a :: TYPE 'WordRep) e s b.+  Parser e s a ->+  Parser e s b ->+  Parser e s b+{-# INLINE sequenceWordParser #-}+sequenceWordParser (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    ) -pureIntPairParser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s.-  a -> Parser e s a-{-# inline pureIntPairParser #-}-pureIntPairParser a = Parser-  (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))+pureIntPairParser ::+  forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s.+  a ->+  Parser e s a+{-# INLINE pureIntPairParser #-}+pureIntPairParser a =+  Parser+    (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #)) -bindIntPairParser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s b.-  Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindIntPairParser #-}-bindIntPairParser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+bindIntPairParser ::+  forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s b.+  Parser e s a ->+  (a -> Parser e s b) ->+  Parser e s b+{-# INLINE bindIntPairParser #-}+bindIntPairParser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    ) -pureInt5Parser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])) e s.-  a -> Parser e s a-{-# inline pureInt5Parser #-}-pureInt5Parser a = Parser-  (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #))+pureInt5Parser ::+  forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])) e s.+  a ->+  Parser e s a+{-# INLINE pureInt5Parser #-}+pureInt5Parser a =+  Parser+    (\(# _, b, c #) s -> (# s, (# | (# a, b, c #) #) #)) -bindInt5Parser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])) e s b.-  Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindInt5Parser #-}-bindInt5Parser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+bindInt5Parser ::+  forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])) e s b.+  Parser e s a ->+  (a -> Parser e s b) ->+  Parser e s b+{-# INLINE bindInt5Parser #-}+bindInt5Parser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    ) -sequenceInt5Parser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])) e s b.-  Parser e s a -> Parser e s b -> Parser e s b-{-# inline sequenceInt5Parser #-}-sequenceInt5Parser (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+sequenceInt5Parser ::+  forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])) e s b.+  Parser e s a ->+  Parser e s b ->+  Parser e s b+{-# INLINE sequenceInt5Parser #-}+sequenceInt5Parser (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    ) -sequenceIntPairParser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s b.-  Parser e s a -> Parser e s b -> Parser e s b-{-# inline sequenceIntPairParser #-}-sequenceIntPairParser (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+sequenceIntPairParser ::+  forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s b.+  Parser e s a ->+  Parser e s b ->+  Parser e s b+{-# INLINE sequenceIntPairParser #-}+sequenceIntPairParser (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    ) -bindInt2to5Parser :: forall-  (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep]))-  (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep]))-  e s.-  Parser e s a -> (a -> Parser e s b) -> Parser e s b-{-# inline bindInt2to5Parser #-}-bindInt2to5Parser (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+bindInt2to5Parser ::+  forall+    (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep]))+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep]))+    e+    s.+  Parser e s a ->+  (a -> Parser e s b) ->+  Parser e s b+{-# INLINE bindInt2to5Parser #-}+bindInt2to5Parser (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    ) -sequenceInt2to5Parser :: forall-  (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep]))-  (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep]))-  e s.-  Parser e s a -> Parser e s b -> Parser e s b-{-# inline sequenceInt2to5Parser #-}-sequenceInt2to5Parser (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+sequenceInt2to5Parser ::+  forall+    (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep]))+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep]))+    e+    s.+  Parser e s a ->+  Parser e s b ->+  Parser e s b+{-# INLINE sequenceInt2to5Parser #-}+sequenceInt2to5Parser (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    )  instance Bind LiftedRep LiftedRep where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindParser   (>>) = sequenceParser  instance Bind 'WordRep LiftedRep where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindWordParser   (>>) = sequenceWordParser  instance Bind 'IntRep LiftedRep where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindIntParser   (>>) = sequenceIntParser  instance Bind ('TupleRep '[ 'IntRep, 'IntRep]) LiftedRep where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindIntPairParser   (>>) = sequenceIntPairParser --instance Bind ('TupleRep '[ 'IntRep, 'IntRep])-              ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])+instance+  Bind+    ('TupleRep '[ 'IntRep, 'IntRep])+    ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])   where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindInt2to5Parser   (>>) = sequenceInt2to5Parser -instance Bind ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])-              LiftedRep+instance+  Bind+    ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])+    LiftedRep   where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindInt5Parser   (>>) = sequenceInt5Parser --instance Bind 'IntRep-              ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])+instance+  Bind+    'IntRep+    ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])   where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindFromIntToInt5   (>>) = sequenceIntToInt5  instance Bind LiftedRep ('TupleRep '[ 'IntRep, 'IntRep]) where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindFromLiftedToIntPair   (>>) = sequenceLiftedToIntPair -instance Bind LiftedRep-              ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])+instance+  Bind+    LiftedRep+    ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])   where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindFromLiftedToInt5   (>>) = sequenceLiftedToInt5  instance Bind 'IntRep ('TupleRep '[ 'IntRep, 'IntRep]) where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindFromIntToIntPair   (>>) = sequenceIntToIntPair  instance Bind LiftedRep 'IntRep where-  {-# inline (>>=) #-}-  {-# inline (>>) #-}+  {-# INLINE (>>=) #-}+  {-# INLINE (>>) #-}   (>>=) = bindFromLiftedToInt   (>>) = sequenceLiftedToInt  instance Pure LiftedRep where-  {-# inline pure #-}+  {-# INLINE pure #-}   pure = pureParser  instance Pure 'IntRep where-  {-# inline pure #-}+  {-# INLINE pure #-}   pure = pureIntParser  instance Pure ('TupleRep '[ 'IntRep, 'IntRep]) where-  {-# inline pure #-}+  {-# INLINE pure #-}   pure = pureIntPairParser  instance Pure ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep]) where-  {-# inline pure #-}+  {-# INLINE pure #-}   pure = pureInt5Parser  bindFromIntToIntPair ::-     forall s e-       (a :: TYPE 'IntRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep ])).-     Parser s e a-  -> (a -> Parser s e b)-  -> Parser s e b-{-# inline bindFromIntToIntPair #-}-bindFromIntToIntPair (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE 'IntRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])).+  Parser s e a ->+  (a -> Parser s e b) ->+  Parser s e b+{-# INLINE bindFromIntToIntPair #-}+bindFromIntToIntPair (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  sequenceIntToIntPair ::-     forall s e-       (a :: TYPE 'IntRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep ])).-     Parser s e a-  -> Parser s e b-  -> Parser s e b-{-# inline sequenceIntToIntPair #-}-sequenceIntToIntPair (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE 'IntRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])).+  Parser s e a ->+  Parser s e b ->+  Parser s e b+{-# INLINE sequenceIntToIntPair #-}+sequenceIntToIntPair (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    )  bindFromIntToInt5 ::-     forall s e-       (a :: TYPE 'IntRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep ])).-     Parser s e a-  -> (a -> Parser s e b)-  -> Parser s e b-{-# inline bindFromIntToInt5 #-}-bindFromIntToInt5 (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE 'IntRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])).+  Parser s e a ->+  (a -> Parser s e b) ->+  Parser s e b+{-# INLINE bindFromIntToInt5 #-}+bindFromIntToInt5 (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  sequenceIntToInt5 ::-     forall s e-       (a :: TYPE 'IntRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep ])).-     Parser s e a-  -> Parser s e b-  -> Parser s e b-{-# inline sequenceIntToInt5 #-}-sequenceIntToInt5 (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE 'IntRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])).+  Parser s e a ->+  Parser s e b ->+  Parser s e b+{-# INLINE sequenceIntToInt5 #-}+sequenceIntToInt5 (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    )  bindFromLiftedToIntPair ::-     forall s e-       (a :: TYPE LiftedRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep ])).-     Parser s e a-  -> (a -> Parser s e b)-  -> Parser s e b-{-# inline bindFromLiftedToIntPair #-}-bindFromLiftedToIntPair (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE LiftedRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])).+  Parser s e a ->+  (a -> Parser s e b) ->+  Parser s e b+{-# INLINE bindFromLiftedToIntPair #-}+bindFromLiftedToIntPair (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  sequenceLiftedToIntPair ::-     forall s e-       (a :: TYPE LiftedRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep ])).-     Parser s e a-  -> Parser s e b-  -> Parser s e b-{-# inline sequenceLiftedToIntPair #-}-sequenceLiftedToIntPair (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )-+  forall+    s+    e+    (a :: TYPE LiftedRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])).+  Parser s e a ->+  Parser s e b ->+  Parser s e b+{-# INLINE sequenceLiftedToIntPair #-}+sequenceLiftedToIntPair (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    )  bindFromLiftedToInt5 ::-     forall s e-       (a :: TYPE LiftedRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])).-     Parser s e a-  -> (a -> Parser s e b)-  -> Parser s e b-{-# inline bindFromLiftedToInt5 #-}-bindFromLiftedToInt5 (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE LiftedRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])).+  Parser s e a ->+  (a -> Parser s e b) ->+  Parser s e b+{-# INLINE bindFromLiftedToInt5 #-}+bindFromLiftedToInt5 (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  sequenceLiftedToInt5 ::-     forall s e-       (a :: TYPE LiftedRep)-       (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep ])).-     Parser s e a-  -> Parser s e b-  -> Parser s e b-{-# inline sequenceLiftedToInt5 #-}-sequenceLiftedToInt5 (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE LiftedRep)+    (b :: TYPE ('TupleRep '[ 'IntRep, 'IntRep, 'IntRep, 'IntRep, 'IntRep])).+  Parser s e a ->+  Parser s e b ->+  Parser s e b+{-# INLINE sequenceLiftedToInt5 #-}+sequenceLiftedToInt5 (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    )  bindFromLiftedToInt ::-     forall s e-       (a :: TYPE LiftedRep)-       (b :: TYPE 'IntRep).-     Parser s e a-  -> (a -> Parser s e b)-  -> Parser s e b-{-# inline bindFromLiftedToInt #-}-bindFromLiftedToInt (Parser f) g = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# y, b, c #) #) ->-        runParser (g y) (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE LiftedRep)+    (b :: TYPE 'IntRep).+  Parser s e a ->+  (a -> Parser s e b) ->+  Parser s e b+{-# INLINE bindFromLiftedToInt #-}+bindFromLiftedToInt (Parser f) g =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# y, b, c #) #) ->+            runParser (g y) (# arr, b, c #) s1+    )  sequenceLiftedToInt ::-     forall s e-       (a :: TYPE LiftedRep)-       (b :: TYPE 'IntRep).-     Parser s e a-  -> Parser s e b-  -> Parser s e b-{-# inline sequenceLiftedToInt #-}-sequenceLiftedToInt (Parser f) (Parser g) = Parser-  (\x@(# arr, _, _ #) s0 -> case f x s0 of-    (# s1, r0 #) -> case r0 of-      (# e | #) -> (# s1, (# e | #) #)-      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1-  )+  forall+    s+    e+    (a :: TYPE LiftedRep)+    (b :: TYPE 'IntRep).+  Parser s e a ->+  Parser s e b ->+  Parser s e b+{-# INLINE sequenceLiftedToInt #-}+sequenceLiftedToInt (Parser f) (Parser g) =+  Parser+    ( \x@(# arr, _, _ #) s0 -> case f x s0 of+        (# s1, r0 #) -> case r0 of+          (# e | #) -> (# s1, (# e | #) #)+          (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+    )
src/Data/Bytes/Parser/Types.hs view
@@ -1,41 +1,43 @@-{-# language DeriveFunctor #-}-{-# language DeriveFoldable #-}-{-# language DerivingStrategies #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DerivingStrategies #-}  module Data.Bytes.Parser.Types   ( Parser-  , Result(..)-  , Slice(..)+  , Result (..)+  , Slice (..)   ) where -import Data.Bytes.Parser.Internal (Parser(..))+import Data.Bytes.Parser.Internal (Parser (..))  -- | The result of running a parser. data Result e a-  = Failure e-    -- ^ An error message indicating what went wrong.-  | Success {-# UNPACK #-} !(Slice a)-    -- ^ The parsed value and the number of bytes+  = -- | An error message indicating what went wrong.+    Failure e+  | -- | The parsed value and the number of bytes     -- remaining in parsed slice.-  deriving stock (Eq,Show,Foldable,Functor)+    Success {-# UNPACK #-} !(Slice a)+  deriving stock (Eq, Show, Foldable, Functor) --- | Slicing metadata (an offset and a length) accompanied--- by a value. This does not represent a slice into the--- value. This type is intended to be used as the result--- of an executed parser. In this context the slicing metadata--- describe a slice into to the array (or byte array) that--- from which the value was parsed.------ It is often useful to check the @length@ when a parser--- succeeds since a non-zero length indicates that there--- was additional unconsumed input. The @offset@ is only--- ever needed to construct a new slice (via @Bytes@ or--- @SmallVector@) from the remaining input.+{- | Slicing metadata (an offset and a length) accompanied+by a value. This does not represent a slice into the+value. This type is intended to be used as the result+of an executed parser. In this context the slicing metadata+describe a slice into to the array (or byte array) that+from which the value was parsed.++It is often useful to check the @length@ when a parser+succeeds since a non-zero length indicates that there+was additional unconsumed input. The @offset@ is only+ever needed to construct a new slice (via @Bytes@ or+@SmallVector@) from the remaining input.+-} data Slice a = Slice   { offset :: {-# UNPACK #-} !Int-    -- ^ Offset into the array.+  -- ^ Offset into the array.   , length :: {-# UNPACK #-} !Int-    -- ^ Length of the slice.+  -- ^ Length of the slice.   , value :: a-    -- ^ The structured data that was successfully parsed.-  } deriving stock (Eq,Show,Foldable,Functor)+  -- ^ The structured data that was successfully parsed.+  }+  deriving stock (Eq, Show, Foldable, Functor)
src/Data/Bytes/Parser/Unsafe.hs view
@@ -1,28 +1,22 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language DuplicateRecordFields #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language NamedFieldPuns #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UnboxedTuples #-} --- | Everything in this module is unsafe and can lead to--- nondeterministic output or segfaults if used incorrectly.+{- | Everything in this module is unsafe and can lead to+nondeterministic output or segfaults if used incorrectly.+-} module Data.Bytes.Parser.Unsafe   ( -- * Types-    Parser(..)+    Parser (..)+     -- * Functions   , cursor   , cursor#@@ -34,41 +28,43 @@  import Prelude hiding (length) -import Data.Bytes.Parser.Internal (Parser(..),uneffectful,uneffectfulInt#)-import Data.Bytes.Parser.Internal (Result(..))-import Data.Bytes.Types (Bytes(..))+import Data.Bytes.Parser.Internal (Parser (..), Result (..), uneffectful, uneffectfulInt#)+import Data.Bytes.Types (Bytes (..)) import Data.Primitive (ByteArray)-import GHC.Exts (Int#,Int(I#))-+import GHC.Exts (Int (I#), Int#) --- | Get the current offset into the chunk. Using this makes--- it possible to observe the internal difference between 'Bytes'--- that refer to equivalent slices. Be careful.+{- | Get the current offset into the chunk. Using this makes+it possible to observe the internal difference between 'Bytes'+that refer to equivalent slices. Be careful.+-} cursor :: Parser e s Int-cursor = uneffectful $ \Bytes{offset,length} ->+cursor = uneffectful $ \Bytes {offset, length} ->   Success offset offset length  -- | Variant of 'cursor' with unboxed result. cursor# :: Parser e s Int#-cursor# = uneffectfulInt# $ \Bytes{offset=I# off,length=I# len} -> (# | (# off, off, len #) #)+cursor# = uneffectfulInt# $ \Bytes {offset = I# off, length = I# len} -> (# | (# off, off, len #) #) --- | Return the byte array being parsed. This includes bytes--- that preceed the current offset and may include bytes that--- go beyond the length. This is somewhat dangerous, so only--- use this is you know what you're doing.+{- | Return the byte array being parsed. This includes bytes+that preceed the current offset and may include bytes that+go beyond the length. This is somewhat dangerous, so only+use this is you know what you're doing.+-} expose :: Parser e s ByteArray-expose = uneffectful $ \Bytes{length,offset,array} ->+expose = uneffectful $ \Bytes {length, offset, array} ->   Success array offset length --- | Move the cursor back by @n@ bytes. Precondition: you--- must have previously consumed at least @n@ bytes.+{- | Move the cursor back by @n@ bytes. Precondition: you+must have previously consumed at least @n@ bytes.+-} unconsume :: Int -> Parser e s ()-unconsume n = uneffectful $ \Bytes{length,offset} ->+unconsume n = uneffectful $ \Bytes {length, offset} ->   Success () (offset - n) (length + n) --- | Set the position to the given index. Precondition: the index--- must be valid. It should be the result of an earlier call to--- 'cursor'.+{- | Set the position to the given index. Precondition: the index+must be valid. It should be the result of an earlier call to+'cursor'.+-} jump :: Int -> Parser e s ()-jump ix = uneffectful $ \(Bytes{length,offset}) ->+jump ix = uneffectful $ \(Bytes {length, offset}) ->   Success () ix (length + (offset - ix))
src/Data/Bytes/Parser/Utf8.hs view
@@ -1,37 +1,33 @@-{-# language BangPatterns #-}-{-# language BinaryLiterals #-}-{-# language DataKinds #-}-{-# language DeriveFunctor #-}-{-# language DerivingStrategies #-}-{-# language GADTSyntax #-}-{-# language KindSignatures #-}-{-# language LambdaCase #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language PolyKinds #-}-{-# language RankNTypes #-}-{-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}-{-# language TypeApplications #-}-{-# language UnboxedSums #-}-{-# language UnboxedTuples #-}-{-# language CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BinaryLiterals #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GADTSyntax #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UnboxedTuples #-} --- | Parse input as UTF-8-encoded text. Parsers in this module will--- fail if they encounter a byte above @0x7F@.+{- | Parse input as UTF-8-encoded text. Parsers in this module will+fail if they encounter a byte above @0x7F@.+-} module Data.Bytes.Parser.Utf8   ( -- * Get Character     any#   , shortText   ) where -import Prelude hiding (length,any,fail,takeWhile)+import Prelude hiding (any, fail, length, takeWhile) -import Data.Bits ((.&.),(.|.),unsafeShiftL,xor)-import Data.Bytes.Parser.Internal (Parser(..))+import Data.Bits (unsafeShiftL, xor, (.&.), (.|.))+import Data.Bytes.Parser.Internal (Parser (..)) import Data.Text.Short (ShortText)-import GHC.Exts (Int(I#),Char(C#),Int#,Char#,(-#),(+#),(>#),chr#)-import GHC.Word (Word8(W8#))+import GHC.Exts (Char (C#), Char#, Int (I#), Int#, chr#, (+#), (-#), (>#))+import GHC.Word (Word8 (W8#))  import qualified Data.ByteString.Short.Internal as BSS import qualified Data.Bytes.Parser as Parser@@ -39,6 +35,7 @@ import qualified Data.Text.Short as TS import qualified GHC.Exts as Exts +{- FOURMOLU_DISABLE -} -- | Interpret the next one to four bytes as a UTF-8-encoded character. -- Fails if the decoded codepoint is in the range U+D800 through U+DFFF. any# :: e -> Parser e s Char#@@ -81,39 +78,46 @@              | otherwise -> (# s0, (# e | #) #)     _ -> (# s0, (# e | #) #)   )+{- FOURMOLU_ENABLE -}  codepointFromFourBytes :: Word8 -> Word8 -> Word8 -> Word8 -> Char-codepointFromFourBytes w1 w2 w3 w4 = C#-  ( chr#-    ( unI $ fromIntegral-      ( unsafeShiftL (word8ToWord w1 .&. 0b00001111) 18 .|.-        unsafeShiftL (word8ToWord w2 .&. 0b00111111) 12 .|.-        unsafeShiftL (word8ToWord w3 .&. 0b00111111) 6 .|.-        (word8ToWord w4 .&. 0b00111111)-      )+codepointFromFourBytes w1 w2 w3 w4 =+  C#+    ( chr#+        ( unI $+            fromIntegral+              ( unsafeShiftL (word8ToWord w1 .&. 0b00001111) 18+                  .|. unsafeShiftL (word8ToWord w2 .&. 0b00111111) 12+                  .|. unsafeShiftL (word8ToWord w3 .&. 0b00111111) 6+                  .|. (word8ToWord w4 .&. 0b00111111)+              )+        )     )-  )  codepointFromThreeBytes :: Word8 -> Word8 -> Word8 -> Char-codepointFromThreeBytes w1 w2 w3 = C#-  ( chr#-    ( unI $ fromIntegral-      ( unsafeShiftL (word8ToWord w1 .&. 0b00001111) 12 .|.-        unsafeShiftL (word8ToWord w2 .&. 0b00111111) 6 .|.-        (word8ToWord w3 .&. 0b00111111)-      )+codepointFromThreeBytes w1 w2 w3 =+  C#+    ( chr#+        ( unI $+            fromIntegral+              ( unsafeShiftL (word8ToWord w1 .&. 0b00001111) 12+                  .|. unsafeShiftL (word8ToWord w2 .&. 0b00111111) 6+                  .|. (word8ToWord w3 .&. 0b00111111)+              )+        )     )-  )  codepointFromTwoBytes :: Word8 -> Word8 -> Char-codepointFromTwoBytes w1 w2 = C#-  ( chr#-    ( unI $ fromIntegral @Word @Int-      ( unsafeShiftL (word8ToWord w1 .&. 0b00011111) 6 .|.-        (word8ToWord w2 .&. 0b00111111)-      )+codepointFromTwoBytes w1 w2 =+  C#+    ( chr#+        ( unI $+            fromIntegral @Word @Int+              ( unsafeShiftL (word8ToWord w1 .&. 0b00011111) 6+                  .|. (word8ToWord w2 .&. 0b00111111)+              )+        )     )-  )  oneByteChar :: Word8 -> Bool oneByteChar !w = w .&. 0b10000000 == 0@@ -136,13 +140,16 @@ unI :: Int -> Int# unI (I# w) = w --- | Consume input that matches the argument. Fails if the--- input does not match.+{- | Consume input that matches the argument. Fails if the+input does not match.+-} shortText :: e -> ShortText -> Parser e s ()-shortText e !t = Parser.byteArray e-  (shortByteStringToByteArray (TS.toShortByteString t))+shortText e !t =+  Parser.byteArray+    e+    (shortByteStringToByteArray (TS.toShortByteString t))  shortByteStringToByteArray ::-     BSS.ShortByteString-  -> PM.ByteArray+  BSS.ShortByteString ->+  PM.ByteArray shortByteStringToByteArray (BSS.SBS x) = PM.ByteArray x
test/Main.hs view
@@ -1,31 +1,32 @@-{-# language BangPatterns #-}-{-# language DataKinds #-}-{-# language MagicHash #-}-{-# language MultiWayIf #-}-{-# language NumDecimals #-}-{-# language OverloadedStrings #-}-{-# language ScopedTypeVariables #-}-{-# language TypeApplications #-}-+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -fno-warn-orphans #-} +#if MIN_VERSION_base(4,18,0)+#else import Control.Applicative (liftA2)+#endif import Control.Monad (replicateM) import Control.Monad.ST (runST)-import Data.Bytes.Parser (Slice(Slice))-import Data.Bytes.Types (Bytes(Bytes))+import Data.Bytes.Parser (Slice (Slice))+import Data.Bytes.Types (Bytes (Bytes)) import Data.Char (ord) import Data.Coerce (coerce)-import Data.Int (Int16,Int32)-import Data.Primitive (ByteArray(..),PrimArray(..))+import Data.Int (Int16, Int32)+import Data.Primitive (ByteArray (..), PrimArray (..)) import Data.Text.Short (ShortText)-import Data.WideWord (Word128(Word128))-import Data.Word (Word8,Word64,Word16,Word32)+import Data.WideWord (Word128 (Word128))+import Data.Word (Word16, Word32, Word64, Word8) import Numeric.Natural (Natural)-import System.ByteOrder (Fixed(..),ByteOrder(BigEndian,LittleEndian))-import Test.Tasty (defaultMain,testGroup,TestTree)-import Test.Tasty.HUnit ((@=?),testCase)-import Test.Tasty.QuickCheck ((===),testProperty)+import System.ByteOrder (ByteOrder (BigEndian, LittleEndian), Fixed (..))+import Test.Tasty (TestTree, defaultMain, testGroup)+import Test.Tasty.HUnit (testCase, (@=?))+import Test.Tasty.QuickCheck (testProperty, (===))  import qualified Data.Bits as Bits import qualified Data.Bytes as Bytes@@ -45,404 +46,413 @@ main = defaultMain tests  tests :: TestTree-tests = testGroup "Parser"-  [ testProperty "decStandardInt" $ \i ->-      withSz (show i) $ \str len ->-        P.parseBytes (Latin.decStandardInt ()) str-        ===-        P.Success (Slice len 0 i)-  , testProperty "big-endian-word16-array" $ \(xs :: [Word16]) ->-      let src = Exts.fromList (coerce xs :: [Fixed 'BigEndian Word16])-          res = Exts.fromList xs :: PrimArray Word16-          sz = length xs * 2-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.Success (Slice (sz + 1) 0 res)-      ===-      P.parseBytes (BigEndian.word16Array () (length xs)) bs-  , testProperty "big-endian-word32-array" $ \(xs :: [Word32]) ->-      let src = Exts.fromList (coerce xs :: [Fixed 'BigEndian Word32])-          res = Exts.fromList xs :: PrimArray Word32-          sz = length xs * 4-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.Success (Slice (sz + 1) 0 res)-      ===-      P.parseBytes (BigEndian.word32Array () (length xs)) bs-  , testProperty "little-endian-word32-array" $ \(xs :: [Word32]) ->-      let src = Exts.fromList (coerce xs :: [Fixed 'LittleEndian Word32])-          res = Exts.fromList xs :: PrimArray Word32-          sz = length xs * 4-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.Success (Slice (sz + 1) 0 res)-      ===-      P.parseBytes (LittleEndian.word32Array () (length xs)) bs-  , testProperty "big-endian-word64-array" $ \(xs :: [Word64]) ->-      let src = Exts.fromList (coerce xs :: [Fixed 'BigEndian Word64])-          res = Exts.fromList xs :: PrimArray Word64-          sz = length xs * 8-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.Success (Slice (sz + 1) 0 res)-      ===-      P.parseBytes (BigEndian.word64Array () (length xs)) bs-  , testProperty "little-endian-word64-array" $ \(xs :: [Word64]) ->-      let src = Exts.fromList (coerce xs :: [Fixed 'LittleEndian Word64])-          res = Exts.fromList xs :: PrimArray Word64-          sz = length xs * 8-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.Success (Slice (sz + 1) 0 res)-      ===-      P.parseBytes (LittleEndian.word64Array () (length xs)) bs-  , testProperty "little-endian-word128-array" $ \(xs :: [Word128]) ->-      let src = Exts.fromList xs-          sz = length xs * 16-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.parseBytes (replicateM (length xs) (LittleEndian.word128 ())) bs-      ===-      P.parseBytes (fmap Exts.toList (LittleEndian.word128Array () (length xs))) bs-  , testProperty "big-endian-word128-array" $ \(xs :: [Word128]) ->-      let src = Exts.fromList xs-          sz = length xs * 16-          bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz-       in-      P.parseBytes (replicateM (length xs) (BigEndian.word128 ())) bs-      ===-      P.parseBytes (fmap Exts.toList (BigEndian.word128Array () (length xs))) bs-  , testProperty "cstring" $ \(xs :: [Word8]) ->-      let ys = Exts.fromList xs-          bs = Bytes.singleton 0x31 <> ys-       in-      P.parseBytes (P.cstring () (Exts.Ptr "1"# ) *> P.bytes () ys *> pure 42) bs-      ===-      (P.Success (Slice (Bytes.length ys + 1) 0 42) :: P.Result () Integer)-  , testCase "big-endian-word256" $-      P.parseBytesMaybe (BigEndian.word256Array () 1) (Exts.fromList [-        0x12, 0x34, 0x56, 0x78, 0x90,-        0x12, 0x34, 0x56, 0x78, 0x90,-        0x12, 0x34, 0x56, 0x78, 0x90,-        0x12,-        0x12, 0x34, 0x56, 0x78, 0x90,-        0x12, 0x34, 0x56, 0x78, 0x90,-        0x12, 0x34, 0x56, 0x78, 0x90,-        0x12-      ])-      @=?-      Just (Exts.fromList [0x1234567890123456789012345678901212345678901234567890123456789012])-  , testProperty "big-endian-word64" bigEndianWord64-  , testProperty "big-endian-word32" bigEndianWord32-  , testProperty "little-endian-word32" littleEndianWord32-  , testCase "delimit" $-      P.Success (Slice 13 0 (167,14625))-      @=?-      P.parseBytes-        (do len <- Latin.decUnsignedInt ()-            Latin.char () ','-            r <- P.delimit () () len $ (,)-              <$> Latin.decUnsignedInt ()-              <*  Latin.char () '*'-              <*> Latin.decUnsignedInt ()-            Latin.char () '0'-            pure r-        ) (bytes "9,167*146250")-  , testGroup "decUnsignedInt"-    [ testCase "A" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decUnsignedInt ())-          (bytes "742493495120739103935542")-    , testCase "B" $-        P.Success (Slice 8 3 4654667)-        @=?-        P.parseBytes (Latin.decUnsignedInt ())-          (bytes "4654667,55")-    , testCase "C" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decUnsignedInt ())-          (bytes ('1' : show (maxBound :: Int)))-    , testCase "D" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decUnsignedInt ())-          (bytes "2481030337885070917891")-    , testCase "E" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decUnsignedInt ())-          (bytes (show (fromIntegral @Int @Word maxBound + 1)))-    , testCase "F" $ withSz (show (maxBound :: Int)) $ \str len ->-        P.Success (Slice len 0 maxBound)-        @=?-        P.parseBytes (Latin.decUnsignedInt ()) str-    , testProperty "property" $ \(QC.NonNegative i) ->-        withSz (show i) $ \str len ->-          P.parseBytes (Latin.decUnsignedInt ()) str-          ===-          P.Success (Slice len 0 i)-    ]-  , testGroup "hexNibbleLower"-    [ testCase "A" $-        P.parseBytes (Latin.hexNibbleLower ()) (bytes "Ab") @=? P.Failure ()-    , testCase "B" $-        P.parseBytes (Latin.hexNibbleLower ()) (bytes "bA") @=? P.Success (Slice 2 1 0xb)-    , testCase "C" $-        P.parseBytes (Latin.hexNibbleLower ()) (bytes "") @=? P.Failure ()-    ]-  , testGroup "tryHexNibbleLower"-    [ testCase "A" $-        P.Success @() (Slice 1 2 Nothing)-        @=?-        P.parseBytes Latin.tryHexNibbleLower (bytes "Ab")-    , testCase "B" $-        P.Success @() (Slice 2 1 (Just 0xb))-        @=?-        P.parseBytes Latin.tryHexNibbleLower (bytes "bA")-    , testCase "C" $-        P.Success @() (Slice 1 0 Nothing)-        @=?-        P.parseBytes Latin.tryHexNibbleLower (bytes "")-    ]-  , testGroup "decPositiveInteger"-    [ testCase "A" $-        P.parseBytes (Latin.decUnsignedInteger ())-          (bytes "5469999463123462573426452736423546373235260")-        @=?-        P.Success-          (Slice 44 0 5469999463123462573426452736423546373235260)-    , testProperty "property" $ \(LargeInteger i) ->+tests =+  testGroup+    "Parser"+    [ testProperty "decStandardInt" $ \i ->         withSz (show i) $ \str len ->-          i >= 0-          QC.==>-          P.parseBytes (Latin.decUnsignedInteger ()) str-          ===-          P.Success (Slice len 0 i)-    ]-  , testGroup "decTrailingInteger"-    [ testProperty "property" $ \(LargeInteger i) ->-        withSz (show i) $ \str sz ->-          i >= 0-          QC.==>-          P.parseBytes (Latin.decTrailingInteger 2) str-          ===-          (P.Success (Slice sz 0 (read ('2' : show i) :: Integer)) :: P.Result () Integer)-    ]-  , testGroup "decSignedInteger"-    [ testCase "A" $-        P.parseBytes (Latin.decSignedInteger ())-          (bytes "-54699994631234625734264527364235463732352601")-        @=?-        P.Success-          ( Slice 46 0-            (-54699994631234625734264527364235463732352601)+          P.parseBytes (Latin.decStandardInt ()) str+            === P.Success (Slice len 0 i)+    , testProperty "big-endian-word16-array" $ \(xs :: [Word16]) ->+        let src = Exts.fromList (coerce xs :: [Fixed 'BigEndian Word16])+            res = Exts.fromList xs :: PrimArray Word16+            sz = length xs * 2+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.Success (Slice (sz + 1) 0 res)+              === P.parseBytes (BigEndian.word16Array () (length xs)) bs+    , testProperty "big-endian-word32-array" $ \(xs :: [Word32]) ->+        let src = Exts.fromList (coerce xs :: [Fixed 'BigEndian Word32])+            res = Exts.fromList xs :: PrimArray Word32+            sz = length xs * 4+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.Success (Slice (sz + 1) 0 res)+              === P.parseBytes (BigEndian.word32Array () (length xs)) bs+    , testProperty "little-endian-word32-array" $ \(xs :: [Word32]) ->+        let src = Exts.fromList (coerce xs :: [Fixed 'LittleEndian Word32])+            res = Exts.fromList xs :: PrimArray Word32+            sz = length xs * 4+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.Success (Slice (sz + 1) 0 res)+              === P.parseBytes (LittleEndian.word32Array () (length xs)) bs+    , testProperty "big-endian-word64-array" $ \(xs :: [Word64]) ->+        let src = Exts.fromList (coerce xs :: [Fixed 'BigEndian Word64])+            res = Exts.fromList xs :: PrimArray Word64+            sz = length xs * 8+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.Success (Slice (sz + 1) 0 res)+              === P.parseBytes (BigEndian.word64Array () (length xs)) bs+    , testProperty "little-endian-word64-array" $ \(xs :: [Word64]) ->+        let src = Exts.fromList (coerce xs :: [Fixed 'LittleEndian Word64])+            res = Exts.fromList xs :: PrimArray Word64+            sz = length xs * 8+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.Success (Slice (sz + 1) 0 res)+              === P.parseBytes (LittleEndian.word64Array () (length xs)) bs+    , testProperty "little-endian-word128-array" $ \(xs :: [Word128]) ->+        let src = Exts.fromList xs+            sz = length xs * 16+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.parseBytes (replicateM (length xs) (LittleEndian.word128 ())) bs+              === P.parseBytes (fmap Exts.toList (LittleEndian.word128Array () (length xs))) bs+    , testProperty "big-endian-word128-array" $ \(xs :: [Word128]) ->+        let src = Exts.fromList xs+            sz = length xs * 16+            bs = Bytes (Exts.fromList [0x42 :: Word8] <> untype src) 1 sz+         in P.parseBytes (replicateM (length xs) (BigEndian.word128 ())) bs+              === P.parseBytes (fmap Exts.toList (BigEndian.word128Array () (length xs))) bs+    , testProperty "cstring" $ \(xs :: [Word8]) ->+        let ys = Exts.fromList xs+            bs = Bytes.singleton 0x31 <> ys+         in P.parseBytes (P.cstring () (Exts.Ptr "1"#) *> P.bytes () ys *> pure 42) bs+              === (P.Success (Slice (Bytes.length ys + 1) 0 42) :: P.Result () Integer)+    , testCase "big-endian-word256" $+        P.parseBytesMaybe+          (BigEndian.word256Array () 1)+          ( Exts.fromList+              [ 0x12+              , 0x34+              , 0x56+              , 0x78+              , 0x90+              , 0x12+              , 0x34+              , 0x56+              , 0x78+              , 0x90+              , 0x12+              , 0x34+              , 0x56+              , 0x78+              , 0x90+              , 0x12+              , 0x12+              , 0x34+              , 0x56+              , 0x78+              , 0x90+              , 0x12+              , 0x34+              , 0x56+              , 0x78+              , 0x90+              , 0x12+              , 0x34+              , 0x56+              , 0x78+              , 0x90+              , 0x12+              ]           )-    , testCase "B" $ -        P.Success (Slice 25 0 (3,(-206173954435705292503)))-        @=?-        P.parseBytes-          ( pure (,)-            <*> Latin.decSignedInteger ()-            <*  Latin.char () 'e'-            <*> Latin.decSignedInteger ()-          ) (bytes "3e-206173954435705292503")-    , testProperty "property" $ \(LargeInteger i) ->-        withSz (show i) $ \str len ->-          P.parseBytes (Latin.decSignedInteger ()) str-          ===-          P.Success (Slice len 0 i)-    ]-  , testGroup "decSignedInt"-    [ testProperty "A" $ \i -> withSz (show i) $ \str len ->-        P.parseBytes (Latin.decSignedInt ()) str-        ===-        P.Success (Slice len 0 i)-    , testProperty "B" $ \i ->-        let s = (if i >= 0 then "+" else "") ++ show i in-        withSz s $ \str len ->-          P.parseBytes (Latin.decSignedInt ()) str-          ===-          P.Success (Slice len 0 i)-    , testCase "C" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decSignedInt ())-          (bytes ('1' : show (maxBound :: Int)))-    , testCase "D" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decSignedInt ())-          (bytes ('-' : '3' : show (maxBound :: Int)))-    , testCase "E" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decSignedInt ())-          (bytes "2481030337885070917891")-    , testCase "F" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decSignedInt ())-          (bytes "-4305030950553840988981")-    , testCase "G" $ withSz (show (minBound :: Int)) $ \str len ->-        P.Success (Slice len 0 minBound)-        @=?-        P.parseBytes (Latin.decSignedInt ()) str-    , testCase "H" $ withSz (show (maxBound :: Int)) $ \str len ->-        P.Success (Slice len 0 maxBound)-        @=?-        P.parseBytes (Latin.decSignedInt ()) str-    , testCase "I" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decSignedInt ())-          (bytes (show (fromIntegral @Int @Word maxBound + 1)))-    , testCase "J" $-        -- This is one number lower than the minimum bound for-        -- a signed 64-bit number, but this test will pass on-        -- 32-bit architectures as well.-        P.Failure ()-        @=?-        P.parseBytes (Latin.decSignedInt ())-          (bytes "-9223372036854775809")-    ]-  , testGroup "decWord64"-    [ testCase "A" $-        P.Failure ()-        @=?-        P.parseBytes (Latin.decWord64 ())-          (bytes "2481030337885070917891")-    ]-  , testCase "decWord-composition" $-      P.Success (Slice 6 0 (42,8))-      @=?-      P.parseBytes-        ( pure (,)-        <*> Ascii.decWord ()-        <*  Ascii.char () '.'-        <*> Ascii.decWord ()-        <*  Ascii.char () '.'-        ) (bytes "42.8.")-  , testCase "decWord-replicate" $-      P.Success (Slice 7 0 (Exts.fromList [42,93] :: PrimArray Word))-      @=?-      P.parseBytes-        (P.replicate 2 (Ascii.decWord () <* Ascii.char () '.'))-        (bytes "42.93.")-  , testCase "ascii-takeShortWhile" $-      P.Success (Slice 11 0 (Exts.fromList ["the","world"] :: PM.Array ShortText))-      @=?-      P.parseBytes-        (P.replicate 2 (Ascii.takeShortWhile (/=',') <* Ascii.char () ','))-        (bytes "the,world,")-  , testGroup "hexFixedWord8"-    [ testCase "A" $-        P.parseBytes (Latin.hexFixedWord8 ()) (bytes "A") @=? P.Failure ()-    , testCase "B" $-        P.parseBytes (Latin.hexFixedWord8 ()) (bytes "0A") @=? P.Success (Slice 3 0 0x0A)-    , testCase "C" $-        P.parseBytes (Latin.hexFixedWord8 ()) (bytes "") @=? P.Failure ()-    , testCase "D" $-        P.parseBytes (Latin.hexFixedWord8 ()) (bytes "A!") @=? P.Failure ()-    ]-  , testGroup "hexFixedWord16"-    [ testCase "A" $-        P.parseBytes (Latin.hexFixedWord16 ()) (bytes "A") @=? P.Failure ()-    , testCase "B" $-        P.parseBytes (Latin.hexFixedWord16 ()) (bytes "0A0A") @=? P.Success (Slice 5 0 0x0A0A)-    , testCase "C" $-        P.parseBytes (Latin.hexFixedWord16 ()) (bytes "") @=? P.Failure ()-    , testCase "D" $-        P.parseBytes (Latin.hexFixedWord16 ()) (bytes "A!A!") @=? P.Failure ()-    ]-  , testGroup "hexFixedWord32"-    [ testCase "A" $-        P.parseBytes (Latin.hexFixedWord32 ()) (bytes "A") @=? P.Failure ()-    , testCase "B" $-        P.parseBytes (Latin.hexFixedWord32 ()) (bytes "0A0A0A0A") @=? P.Success (Slice 9 0 0x0A0A0A0A)-    , testCase "C" $-        P.parseBytes (Latin.hexFixedWord32 ()) (bytes "") @=? P.Failure ()-    , testCase "D" $-        P.parseBytes (Latin.hexFixedWord32 ()) (bytes "A!A0A0A0") @=? P.Failure ()-    ]-  , testGroup "hexFixedWord64"-    [ testCase "A" $-        P.parseBytes (Latin.hexFixedWord64 ()) (bytes "ABCD01235678BCDE")-        @=? P.Success-        (Slice 17 0 0xABCD01235678BCDE)-    ]-  , testGroup "base128-w32"-    [ testCase "A" $-        P.Success (Slice 2 0 0x7E)-        @=?-        P.parseBytes (Base128.word32 ()) (bytes "\x7E")-    , testCase "B" $-        P.Success (Slice 5 0 0x200000)-        @=?-        P.parseBytes (Base128.word32 ()) (bytes "\x81\x80\x80\x00")-    , testCase "C" $-        P.Success (Slice 4 0 1656614)-        @=?-        P.parseBytes (Base128.word32 ()) (bytes "\xE5\x8E\x26")-    -- , testProperty "iso" $ \w -> -- TODO-    --     P.parseBytesMaybe (Base.word32 ()) (encodeBase128 (fromIntegral w))-    --     ===-    --     Just w-    ]-  , testGroup "leb128-w32"-    [ testCase "A" $-        P.Success (Slice 2 0 0x7E)-        @=?-        P.parseBytes (Leb128.word32 ()) (bytes "\x7E")-    , testCase "B" $-        P.Success (Slice 5 0 0x200000)-        @=?-        P.parseBytes (Leb128.word32 ()) (bytes "\x80\x80\x80\x01")-    , testCase "C" $-        P.Success (Slice 4 0 624485)-        @=?-        P.parseBytes (Leb128.word32 ()) (bytes "\xE5\x8E\x26")-    , testProperty "iso" $ \w -> -        P.parseBytesMaybe (Leb128.word32 ()) (encodeLeb128 (fromIntegral w))-        ===-        Just w-    ]-  , testGroup "leb128-w16"-    [ testCase "A" $-        P.Failure ()-        @=?-        P.parseBytes (Leb128.word16 ()) (bytes "\x80\x80\x04")-    , testCase "B" $-        P.Success (Slice 4 0 0xFFFF)-        @=?-        P.parseBytes (Leb128.word16 ()) (bytes "\xFF\xFF\x03")-    , testProperty "iso" $ \w -> -        P.parseBytesMaybe (Leb128.word16 ()) (encodeLeb128 (fromIntegral w))-        ===-        Just w-    ]-  , testGroup "leb128-i16"-    [ testProperty "iso" $ \(w :: Int16) -> -        P.parseBytesMaybe (Leb128.int16 ())-          (encodeLeb128 (fromIntegral @Word16 @Natural (zigzag16 w)))-        ===-        Just w-    ]-  , testGroup "leb128-i32"-    [ testProperty "iso" $ \(w :: Int32) -> -        P.parseBytesMaybe (Leb128.int32 ())-          (encodeLeb128 (fromIntegral @Word32 @Natural (zigzag32 w)))-        ===-        Just w-    ]-  , testGroup "satisfy"-    [ testCase "A" $-        P.Success (Slice 2 0 0x20)-        @=?-        P.parseBytes (P.satisfy () (== 0x20)) (bytes "\x20")+          @=? Just (Exts.fromList [0x1234567890123456789012345678901212345678901234567890123456789012])+    , testProperty "big-endian-word64" bigEndianWord64+    , testProperty "big-endian-word32" bigEndianWord32+    , testProperty "little-endian-word32" littleEndianWord32+    , testCase "delimit" $+        P.Success (Slice 13 0 (167, 14625))+          @=? P.parseBytes+            ( do+                len <- Latin.decUnsignedInt ()+                Latin.char () ','+                r <-+                  P.delimit () () len $+                    (,)+                      <$> Latin.decUnsignedInt ()+                      <* Latin.char () '*'+                      <*> Latin.decUnsignedInt ()+                Latin.char () '0'+                pure r+            )+            (bytes "9,167*146250")+    , testGroup+        "decUnsignedInt"+        [ testCase "A" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decUnsignedInt ())+                (bytes "742493495120739103935542")+        , testCase "B" $+            P.Success (Slice 8 3 4654667)+              @=? P.parseBytes+                (Latin.decUnsignedInt ())+                (bytes "4654667,55")+        , testCase "C" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decUnsignedInt ())+                (bytes ('1' : show (maxBound :: Int)))+        , testCase "D" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decUnsignedInt ())+                (bytes "2481030337885070917891")+        , testCase "E" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decUnsignedInt ())+                (bytes (show (fromIntegral @Int @Word maxBound + 1)))+        , testCase "F" $ withSz (show (maxBound :: Int)) $ \str len ->+            P.Success (Slice len 0 maxBound)+              @=? P.parseBytes (Latin.decUnsignedInt ()) str+        , testProperty "property" $ \(QC.NonNegative i) ->+            withSz (show i) $ \str len ->+              P.parseBytes (Latin.decUnsignedInt ()) str+                === P.Success (Slice len 0 i)+        ]+    , testGroup+        "hexNibbleLower"+        [ testCase "A" $+            P.parseBytes (Latin.hexNibbleLower ()) (bytes "Ab") @=? P.Failure ()+        , testCase "B" $+            P.parseBytes (Latin.hexNibbleLower ()) (bytes "bA") @=? P.Success (Slice 2 1 0xb)+        , testCase "C" $+            P.parseBytes (Latin.hexNibbleLower ()) (bytes "") @=? P.Failure ()+        ]+    , testGroup+        "tryHexNibbleLower"+        [ testCase "A" $+            P.Success @() (Slice 1 2 Nothing)+              @=? P.parseBytes Latin.tryHexNibbleLower (bytes "Ab")+        , testCase "B" $+            P.Success @() (Slice 2 1 (Just 0xb))+              @=? P.parseBytes Latin.tryHexNibbleLower (bytes "bA")+        , testCase "C" $+            P.Success @() (Slice 1 0 Nothing)+              @=? P.parseBytes Latin.tryHexNibbleLower (bytes "")+        ]+    , testGroup+        "decPositiveInteger"+        [ testCase "A" $+            P.parseBytes+              (Latin.decUnsignedInteger ())+              (bytes "5469999463123462573426452736423546373235260")+              @=? P.Success+                (Slice 44 0 5469999463123462573426452736423546373235260)+        , testProperty "property" $ \(LargeInteger i) ->+            withSz (show i) $ \str len ->+              i+                >= 0+                  QC.==> P.parseBytes (Latin.decUnsignedInteger ()) str+                  === P.Success (Slice len 0 i)+        ]+    , testGroup+        "decTrailingInteger"+        [ testProperty "property" $ \(LargeInteger i) ->+            withSz (show i) $ \str sz ->+              i+                >= 0+                  QC.==> P.parseBytes (Latin.decTrailingInteger 2) str+                  === (P.Success (Slice sz 0 (read ('2' : show i) :: Integer)) :: P.Result () Integer)+        ]+    , testGroup+        "decSignedInteger"+        [ testCase "A" $+            P.parseBytes+              (Latin.decSignedInteger ())+              (bytes "-54699994631234625734264527364235463732352601")+              @=? P.Success+                ( Slice+                    46+                    0+                    (-54699994631234625734264527364235463732352601)+                )+        , testCase "B" $+            P.Success (Slice 25 0 (3, (-206173954435705292503)))+              @=? P.parseBytes+                ( pure (,)+                    <*> Latin.decSignedInteger ()+                    <* Latin.char () 'e'+                    <*> Latin.decSignedInteger ()+                )+                (bytes "3e-206173954435705292503")+        , testProperty "property" $ \(LargeInteger i) ->+            withSz (show i) $ \str len ->+              P.parseBytes (Latin.decSignedInteger ()) str+                === P.Success (Slice len 0 i)+        ]+    , testGroup+        "decSignedInt"+        [ testProperty "A" $ \i -> withSz (show i) $ \str len ->+            P.parseBytes (Latin.decSignedInt ()) str+              === P.Success (Slice len 0 i)+        , testProperty "B" $ \i ->+            let s = (if i >= 0 then "+" else "") ++ show i+             in withSz s $ \str len ->+                  P.parseBytes (Latin.decSignedInt ()) str+                    === P.Success (Slice len 0 i)+        , testCase "C" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decSignedInt ())+                (bytes ('1' : show (maxBound :: Int)))+        , testCase "D" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decSignedInt ())+                (bytes ('-' : '3' : show (maxBound :: Int)))+        , testCase "E" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decSignedInt ())+                (bytes "2481030337885070917891")+        , testCase "F" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decSignedInt ())+                (bytes "-4305030950553840988981")+        , testCase "G" $ withSz (show (minBound :: Int)) $ \str len ->+            P.Success (Slice len 0 minBound)+              @=? P.parseBytes (Latin.decSignedInt ()) str+        , testCase "H" $ withSz (show (maxBound :: Int)) $ \str len ->+            P.Success (Slice len 0 maxBound)+              @=? P.parseBytes (Latin.decSignedInt ()) str+        , testCase "I" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decSignedInt ())+                (bytes (show (fromIntegral @Int @Word maxBound + 1)))+        , testCase "J" $+            -- This is one number lower than the minimum bound for+            -- a signed 64-bit number, but this test will pass on+            -- 32-bit architectures as well.+            P.Failure ()+              @=? P.parseBytes+                (Latin.decSignedInt ())+                (bytes "-9223372036854775809")+        ]+    , testGroup+        "decWord64"+        [ testCase "A" $+            P.Failure ()+              @=? P.parseBytes+                (Latin.decWord64 ())+                (bytes "2481030337885070917891")+        ]+    , testCase "decWord-composition" $+        P.Success (Slice 6 0 (42, 8))+          @=? P.parseBytes+            ( pure (,)+                <*> Ascii.decWord ()+                <* Ascii.char () '.'+                <*> Ascii.decWord ()+                <* Ascii.char () '.'+            )+            (bytes "42.8.")+    , testCase "decWord-replicate" $+        P.Success (Slice 7 0 (Exts.fromList [42, 93] :: PrimArray Word))+          @=? P.parseBytes+            (P.replicate 2 (Ascii.decWord () <* Ascii.char () '.'))+            (bytes "42.93.")+    , testCase "ascii-takeShortWhile" $+        P.Success (Slice 11 0 (Exts.fromList ["the", "world"] :: PM.Array ShortText))+          @=? P.parseBytes+            (P.replicate 2 (Ascii.takeShortWhile (/= ',') <* Ascii.char () ','))+            (bytes "the,world,")+    , testGroup+        "hexFixedWord8"+        [ testCase "A" $+            P.parseBytes (Latin.hexFixedWord8 ()) (bytes "A") @=? P.Failure ()+        , testCase "B" $+            P.parseBytes (Latin.hexFixedWord8 ()) (bytes "0A") @=? P.Success (Slice 3 0 0x0A)+        , testCase "C" $+            P.parseBytes (Latin.hexFixedWord8 ()) (bytes "") @=? P.Failure ()+        , testCase "D" $+            P.parseBytes (Latin.hexFixedWord8 ()) (bytes "A!") @=? P.Failure ()+        ]+    , testGroup+        "hexFixedWord16"+        [ testCase "A" $+            P.parseBytes (Latin.hexFixedWord16 ()) (bytes "A") @=? P.Failure ()+        , testCase "B" $+            P.parseBytes (Latin.hexFixedWord16 ()) (bytes "0A0A") @=? P.Success (Slice 5 0 0x0A0A)+        , testCase "C" $+            P.parseBytes (Latin.hexFixedWord16 ()) (bytes "") @=? P.Failure ()+        , testCase "D" $+            P.parseBytes (Latin.hexFixedWord16 ()) (bytes "A!A!") @=? P.Failure ()+        ]+    , testGroup+        "hexFixedWord32"+        [ testCase "A" $+            P.parseBytes (Latin.hexFixedWord32 ()) (bytes "A") @=? P.Failure ()+        , testCase "B" $+            P.parseBytes (Latin.hexFixedWord32 ()) (bytes "0A0A0A0A") @=? P.Success (Slice 9 0 0x0A0A0A0A)+        , testCase "C" $+            P.parseBytes (Latin.hexFixedWord32 ()) (bytes "") @=? P.Failure ()+        , testCase "D" $+            P.parseBytes (Latin.hexFixedWord32 ()) (bytes "A!A0A0A0") @=? P.Failure ()+        ]+    , testGroup+        "hexFixedWord64"+        [ testCase "A" $+            P.parseBytes (Latin.hexFixedWord64 ()) (bytes "ABCD01235678BCDE")+              @=? P.Success+                (Slice 17 0 0xABCD01235678BCDE)+        ]+    , testGroup+        "base128-w32"+        [ testCase "A" $+            P.Success (Slice 2 0 0x7E)+              @=? P.parseBytes (Base128.word32 ()) (bytes "\x7E")+        , testCase "B" $+            P.Success (Slice 5 0 0x200000)+              @=? P.parseBytes (Base128.word32 ()) (bytes "\x81\x80\x80\x00")+        , testCase "C" $+            P.Success (Slice 4 0 1656614)+              @=? P.parseBytes (Base128.word32 ()) (bytes "\xE5\x8E\x26")+              -- , testProperty "iso" $ \w -> -- TODO+              --     P.parseBytesMaybe (Base.word32 ()) (encodeBase128 (fromIntegral w))+              --     ===+              --     Just w+        ]+    , testGroup+        "leb128-w32"+        [ testCase "A" $+            P.Success (Slice 2 0 0x7E)+              @=? P.parseBytes (Leb128.word32 ()) (bytes "\x7E")+        , testCase "B" $+            P.Success (Slice 5 0 0x200000)+              @=? P.parseBytes (Leb128.word32 ()) (bytes "\x80\x80\x80\x01")+        , testCase "C" $+            P.Success (Slice 4 0 624485)+              @=? P.parseBytes (Leb128.word32 ()) (bytes "\xE5\x8E\x26")+        , testProperty "iso" $ \w ->+            P.parseBytesMaybe (Leb128.word32 ()) (encodeLeb128 (fromIntegral w))+              === Just w+        ]+    , testGroup+        "leb128-w16"+        [ testCase "A" $+            P.Failure ()+              @=? P.parseBytes (Leb128.word16 ()) (bytes "\x80\x80\x04")+        , testCase "B" $+            P.Success (Slice 4 0 0xFFFF)+              @=? P.parseBytes (Leb128.word16 ()) (bytes "\xFF\xFF\x03")+        , testProperty "iso" $ \w ->+            P.parseBytesMaybe (Leb128.word16 ()) (encodeLeb128 (fromIntegral w))+              === Just w+        ]+    , testGroup+        "leb128-i16"+        [ testProperty "iso" $ \(w :: Int16) ->+            P.parseBytesMaybe+              (Leb128.int16 ())+              (encodeLeb128 (fromIntegral @Word16 @Natural (zigzag16 w)))+              === Just w+        ]+    , testGroup+        "leb128-i32"+        [ testProperty "iso" $ \(w :: Int32) ->+            P.parseBytesMaybe+              (Leb128.int32 ())+              (encodeLeb128 (fromIntegral @Word32 @Natural (zigzag32 w)))+              === Just w+        ]+    , testGroup+        "satisfy"+        [ testCase "A" $+            P.Success (Slice 2 0 0x20)+              @=? P.parseBytes (P.satisfy () (== 0x20)) (bytes "\x20")+        ]     ]-  ]  bytes :: String -> Bytes bytes s = let b = pack ('x' : s) in Bytes b 1 (PM.sizeofByteArray b - 1)@@ -451,9 +461,15 @@ pack = Exts.fromList . map (fromIntegral @Int @Word8 . ord)  bigEndianWord64 ::-     Word8 -> Word8 -> Word8 -> Word8-  -> Word8 -> Word8 -> Word8 -> Word8-  -> QC.Property+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  QC.Property bigEndianWord64 a b c d e f g h =   let arr = runST $ do         m <- PM.newByteArray 11@@ -469,22 +485,25 @@         PM.writeByteArray m 9 (h :: Word8)         PM.writeByteArray m 10 (0xEE :: Word8)         PM.unsafeFreezeByteArray m-      expected = (0 :: Word64)-        + fromIntegral a * 256 ^ (7 :: Integer)-        + fromIntegral b * 256 ^ (6 :: Integer)-        + fromIntegral c * 256 ^ (5 :: Integer)-        + fromIntegral d * 256 ^ (4 :: Integer)-        + fromIntegral e * 256 ^ (3 :: Integer)-        + fromIntegral f * 256 ^ (2 :: Integer)-        + fromIntegral g * 256 ^ (1 :: Integer)-        + fromIntegral h * 256 ^ (0 :: Integer)+      expected =+        (0 :: Word64)+          + fromIntegral a * 256 ^ (7 :: Integer)+          + fromIntegral b * 256 ^ (6 :: Integer)+          + fromIntegral c * 256 ^ (5 :: Integer)+          + fromIntegral d * 256 ^ (4 :: Integer)+          + fromIntegral e * 256 ^ (3 :: Integer)+          + fromIntegral f * 256 ^ (2 :: Integer)+          + fromIntegral g * 256 ^ (1 :: Integer)+          + fromIntegral h * 256 ^ (0 :: Integer)    in P.parseBytes (BigEndian.word64 ()) (Bytes arr 2 9)-      ===-      P.Success (Slice 10 1 expected)+        === P.Success (Slice 10 1 expected)  bigEndianWord32 ::-     Word8 -> Word8 -> Word8 -> Word8-  -> QC.Property+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  QC.Property bigEndianWord32 a b c d =   let arr = runST $ do         m <- PM.newByteArray 7@@ -496,18 +515,21 @@         PM.writeByteArray m 5 (d :: Word8)         PM.writeByteArray m 6 (0xEE :: Word8)         PM.unsafeFreezeByteArray m-      expected = (0 :: Word32)-        + fromIntegral a * 256 ^ (3 :: Integer)-        + fromIntegral b * 256 ^ (2 :: Integer)-        + fromIntegral c * 256 ^ (1 :: Integer)-        + fromIntegral d * 256 ^ (0 :: Integer)+      expected =+        (0 :: Word32)+          + fromIntegral a * 256 ^ (3 :: Integer)+          + fromIntegral b * 256 ^ (2 :: Integer)+          + fromIntegral c * 256 ^ (1 :: Integer)+          + fromIntegral d * 256 ^ (0 :: Integer)    in P.parseBytes (BigEndian.word32 ()) (Bytes arr 2 5)-      ===-      P.Success (Slice 6 1 expected)+        === P.Success (Slice 6 1 expected)  littleEndianWord32 ::-     Word8 -> Word8 -> Word8 -> Word8-  -> QC.Property+  Word8 ->+  Word8 ->+  Word8 ->+  Word8 ->+  QC.Property littleEndianWord32 a b c d =   let arr = runST $ do         m <- PM.newByteArray 7@@ -519,33 +541,34 @@         PM.writeByteArray m 5 (d :: Word8)         PM.writeByteArray m 6 (0xEE :: Word8)         PM.unsafeFreezeByteArray m-      expected = (0 :: Word32)-        + fromIntegral a * 256 ^ (0 :: Integer)-        + fromIntegral b * 256 ^ (1 :: Integer)-        + fromIntegral c * 256 ^ (2 :: Integer)-        + fromIntegral d * 256 ^ (3 :: Integer)+      expected =+        (0 :: Word32)+          + fromIntegral a * 256 ^ (0 :: Integer)+          + fromIntegral b * 256 ^ (1 :: Integer)+          + fromIntegral c * 256 ^ (2 :: Integer)+          + fromIntegral d * 256 ^ (3 :: Integer)    in P.parseBytes (LittleEndian.word32 ()) (Bytes arr 2 5)-      ===-      P.Success (Slice 6 1 expected)+        === P.Success (Slice 6 1 expected)  -- The Arbitrary instance for Integer that comes with -- QuickCheck only generates small numbers. newtype LargeInteger = LargeInteger Integer-  deriving (Eq,Show)+  deriving (Eq, Show)  instance QC.Arbitrary Word128 where   arbitrary = liftA2 Word128 QC.arbitrary QC.arbitrary  instance QC.Arbitrary LargeInteger where   arbitrary = do-      n <- QC.choose (1, 27)-      sign <- QC.arbitrary-      r <- (if sign then negate else id) . foldr f 0+    n <- QC.choose (1, 27)+    sign <- QC.arbitrary+    r <-+      (if sign then negate else id) . foldr f 0         <$> replicateM n QC.arbitrary-      pure (LargeInteger r)-    where-      f :: Word8 -> Integer -> Integer-      f w acc = (acc `Bits.shiftL` 8) + fromIntegral w+    pure (LargeInteger r)+   where+    f :: Word8 -> Integer -> Integer+    f w acc = (acc `Bits.shiftL` 8) + fromIntegral w  -- We add an extra 1 since bytes gives us a slice that -- starts at that offset.@@ -556,15 +579,17 @@ untype (PrimArray x) = ByteArray x  encodeLeb128 :: Natural -> Bytes-encodeLeb128 x = Bytes.unsafeDrop 1 (Exts.fromList (0xFF : go [] x)) where+encodeLeb128 x = Bytes.unsafeDrop 1 (Exts.fromList (0xFF : go [] x))+ where   go !xs !n =-    let (q,r) = quotRem n 128+    let (q, r) = quotRem n 128         r' = fromIntegral @Natural @Word8 r-        w = if q == 0-          then r'-          else Bits.setBit r' 7+        w =+          if q == 0+            then r'+            else Bits.setBit r' 7         xs' = w : xs-     in if q == 0 +     in if q == 0           then List.reverse xs'           else go xs' q