{-# language UnboxedTuples #-}

{-|
This module implements a `Parser` supporting a custom reader environment, custom
error types and an `Int` state.
-}

module FlatParse.Stateful (
  -- * Parser types and constructors
    type Parser(..)
  , type Res#
  , pattern OK#
  , pattern Fail#
  , pattern Err#
  , Result(..)

  -- * Running parsers
  , runParser
  , runParserS

  -- * Actions on the state and the environment
  , get
  , put
  , modify
  , ask
  , local

  -- * Errors and failures
  , empty
  , err
  , lookahead
  , fails
  , try
  , optional
  , optional_
  , withOption
  , cut
  , cutting

  -- * Basic lexing and parsing
  , eof
  , takeBs
  , takeRestBs
  , char
  , byte
  , bytes
  , string
  , switch
  , switchWithPost
  , rawSwitchWithPost
  , satisfy
  , satisfy_
  , satisfyASCII
  , satisfyASCII_
  , fusedSatisfy
  , fusedSatisfy_
  , anyWord8
  , anyWord8_
  , anyWord16
  , anyWord16_
  , anyWord32
  , anyWord32_
  , anyWord64
  , anyWord64_
  , anyWord
  , anyWord_
  , anyInt8
  , anyInt16
  , anyInt32
  , anyInt64
  , anyInt
  , anyChar
  , anyChar_
  , anyCharASCII
  , anyCharASCII_
  , isDigit
  , isGreekLetter
  , isLatinLetter
  , FlatParse.Stateful.readInt
  , FlatParse.Stateful.readInteger

  -- ** Explicit-endianness machine integers
  , anyWord16le
  , anyWord16be
  , anyWord32le
  , anyWord32be
  , anyWord64le
  , anyWord64be
  , anyInt16le
  , anyInt16be
  , anyInt32le
  , anyInt32be
  , anyInt64le
  , anyInt64be

  -- * Combinators
  , (<|>)
  , branch
  , chainl
  , chainr
  , many
  , many_
  , some
  , some_
  , notFollowedBy
  , isolate

  -- * Positions and spans
  , Pos(..)
  , Span(..)
  , getPos
  , setPos
  , endPos
  , spanOf
  , withSpan
  , byteStringOf
  , withByteString
  , inSpan

  -- ** Position and span conversions
  , Basic.validPos
  , Basic.posLineCols
  , unsafeSpanToByteString
  , Basic.unsafeSlice
  , Basic.mkPos
  , Basic.lines

  -- * Getting the rest of the input as a 'String'
  , takeLine
  , traceLine
  , takeRest
  , traceRest

  -- * `String` conversions
  , packUTF8
  , Basic.unpackUTF8

  -- * Internal functions
  , ensureBytes#
  , scan8#
  , scan16#
  , scan32#
  , scan64#
  , scanAny8#
  , scanBytes#
  , setBack#

  , withAnyWord8#
  , withAnyWord16#
  , withAnyWord32#
  , withAnyWord64#
  , withAnyInt8#
  , withAnyInt16#
  , withAnyInt32#
  , withAnyInt64#

  ) where

import Control.Monad
import Data.Foldable
import Data.Map (Map)
import GHC.Exts
import GHC.Word
import GHC.Int
import Language.Haskell.TH
import System.IO.Unsafe
import GHC.ForeignPtr

import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.Map.Strict as M

import FlatParse.Internal
import FlatParse.Internal.UnboxedNumerics

import qualified FlatParse.Basic as Basic

--------------------------------------------------------------------------------

-- | Primitive result of a parser. Possible results are given by `OK#`, `Err#` and `Fail#`
--   pattern synonyms.
type Res# e a =
  (#
    (# a, Addr#, Int# #)
  | (# #)
  | (# e #)
  #)

-- | Contains return value, pointer to the rest of the input buffer and the nex `Int`
--   state.
pattern OK# :: a -> Addr# -> Int# -> Res# e a
pattern $bOK# :: a -> Addr# -> Int# -> Res# e a
$mOK# :: forall r a e.
Res# e a -> (a -> Addr# -> Int# -> r) -> (Void# -> r) -> r
OK# a s n = (# (# a, s, n #) | | #)

-- | Constructor for errors which are by default non-recoverable.
pattern Err# :: e -> Res# e a
pattern $bErr# :: e -> Res# e a
$mErr# :: forall r e a. Res# e a -> (e -> r) -> (Void# -> r) -> r
Err# e = (# | | (# e #) #)

-- | Constructor for recoverable failure.
pattern Fail# :: Res# e a
pattern $bFail# :: Void# -> forall e a. Res# e a
$mFail# :: forall r e a. Res# e a -> (Void# -> r) -> (Void# -> r) -> r
Fail# = (# | (# #) | #)
{-# complete OK#, Err#, Fail# #-}

-- | @Parser r e a@ has a reader environment @r@, error type @e@ and a return type @a@.
newtype Parser r e a = Parser {Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# :: ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a}

instance Functor (Parser r e) where
  fmap :: (a -> b) -> Parser r e a -> Parser r e b
fmap a -> b
f (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
g) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
g ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n -> let !b :: b
b = a -> b
f a
a in b -> Addr# -> Int# -> Res# e b
forall a e. a -> Addr# -> Int# -> Res# e a
OK# b
b Addr#
s Int#
n
    Res# e a
x         -> Res# e a -> Res# e b
unsafeCoerce# Res# e a
x
  {-# inline fmap #-}

  <$ :: a -> Parser r e b -> Parser r e a
(<$) a
a' (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
g) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
g ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# b
a Addr#
s Int#
n -> a -> Addr# -> Int# -> Res# e a
forall a e. a -> Addr# -> Int# -> Res# e a
OK# a
a' Addr#
s Int#
n
    Res# e b
x         -> Res# e b -> Res# e a
unsafeCoerce# Res# e b
x
  {-# inline (<$) #-}

instance Applicative (Parser r e) where
  pure :: a -> Parser r e a
pure a
a = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> a -> Addr# -> Int# -> Res# e a
forall a e. a -> Addr# -> Int# -> Res# e a
OK# a
a Addr#
s Int#
n
  {-# inline pure #-}
  Parser ForeignPtrContents
-> r -> Addr# -> Addr# -> Int# -> Res# e (a -> b)
ff <*> :: Parser r e (a -> b) -> Parser r e a -> Parser r e b
<*> Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents
-> r -> Addr# -> Addr# -> Int# -> Res# e (a -> b)
ff ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a -> b
f Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
      OK# a
a Addr#
s Int#
n  -> let !b :: b
b = a -> b
f a
a in b -> Addr# -> Int# -> Res# e b
forall a e. a -> Addr# -> Int# -> Res# e a
OK# b
b Addr#
s Int#
n
      Res# e a
x          -> Res# e a -> Res# e b
unsafeCoerce# Res# e a
x
    Res# e (a -> b)
x -> Res# e (a -> b) -> Res# e b
unsafeCoerce# Res# e (a -> b)
x
  {-# inline (<*>) #-}
  Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa <* :: Parser r e a -> Parser r e b -> Parser r e a
<* Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
fb = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n   -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
fb ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
      OK# b
b Addr#
s Int#
n -> a -> Addr# -> Int# -> Res# e a
forall a e. a -> Addr# -> Int# -> Res# e a
OK# a
a Addr#
s Int#
n
      Res# e b
x -> Res# e b -> Res# e a
unsafeCoerce# Res# e b
x
    Res# e a
x -> Res# e a -> Res# e a
unsafeCoerce# Res# e a
x
  {-# inline (<*) #-}
  Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa *> :: Parser r e a -> Parser r e b -> Parser r e b
*> Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
fb = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n -> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
fb ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
    Res# e a
x         -> Res# e a -> Res# e b
unsafeCoerce# Res# e a
x
  {-# inline (*>) #-}

instance Monad (Parser r e) where
  return :: a -> Parser r e a
return = a -> Parser r e a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  {-# inline return #-}
  Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa >>= :: Parser r e a -> (a -> Parser r e b) -> Parser r e b
>>= a -> Parser r e b
f = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
fa ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n -> Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (a -> Parser r e b
f a
a) ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
    Res# e a
x         -> Res# e a -> Res# e b
unsafeCoerce# Res# e a
x
  {-# inline (>>=) #-}
  >> :: Parser r e a -> Parser r e b -> Parser r e b
(>>) = Parser r e a -> Parser r e b -> Parser r e b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
  {-# inline (>>) #-}

-- | Higher-level boxed data type for parsing results.
data Result e a =
    OK a Int !(B.ByteString)  -- ^ Contains return value, last `Int` state, unconsumed input.
  | Fail                      -- ^ Recoverable-by-default failure.
  | Err !e                    -- ^ Unrecoverble-by-default error.
  deriving Int -> Result e a -> ShowS
[Result e a] -> ShowS
Result e a -> String
(Int -> Result e a -> ShowS)
-> (Result e a -> String)
-> ([Result e a] -> ShowS)
-> Show (Result e a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall e a. (Show a, Show e) => Int -> Result e a -> ShowS
forall e a. (Show a, Show e) => [Result e a] -> ShowS
forall e a. (Show a, Show e) => Result e a -> String
showList :: [Result e a] -> ShowS
$cshowList :: forall e a. (Show a, Show e) => [Result e a] -> ShowS
show :: Result e a -> String
$cshow :: forall e a. (Show a, Show e) => Result e a -> String
showsPrec :: Int -> Result e a -> ShowS
$cshowsPrec :: forall e a. (Show a, Show e) => Int -> Result e a -> ShowS
Show

instance Functor (Result e) where
  fmap :: (a -> b) -> Result e a -> Result e b
fmap a -> b
f (OK a
a Int
s ByteString
n) = let !b :: b
b = a -> b
f a
a in b -> Int -> ByteString -> Result e b
forall e a. a -> Int -> ByteString -> Result e a
OK b
b Int
s ByteString
n
  fmap a -> b
f Result e a
r          = Result e a -> Result e b
unsafeCoerce# Result e a
r
  {-# inline fmap #-}
  <$ :: a -> Result e b -> Result e a
(<$) a
a (OK b
_ Int
s ByteString
n) = a -> Int -> ByteString -> Result e a
forall e a. a -> Int -> ByteString -> Result e a
OK a
a Int
s ByteString
n
  (<$) a
_ Result e b
r          = Result e b -> Result e a
unsafeCoerce# Result e b
r
  {-# inline (<$) #-}

--------------------------------------------------------------------------------

-- | Run a parser. The `Int` argument is the initial state.
runParser :: Parser r e a -> r -> Int -> B.ByteString -> Result e a
runParser :: Parser r e a -> r -> Int -> ByteString -> Result e a
runParser (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) !r
r (I# Int#
n) b :: ByteString
b@(B.PS (ForeignPtr Addr#
_ ForeignPtrContents
fp) Int
_ (I# Int#
len)) = IO (Result e a) -> Result e a
forall a. IO a -> a
unsafeDupablePerformIO do
  ByteString -> (CString -> IO (Result e a)) -> IO (Result e a)
forall a. ByteString -> (CString -> IO a) -> IO a
B.unsafeUseAsCString ByteString
b \(Ptr Addr#
buf) -> do
    let end :: Addr#
end = Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
len
    case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
end Addr#
buf Int#
n of
      Err# e
e ->
        Result e a -> IO (Result e a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (e -> Result e a
forall e a. e -> Result e a
Err e
e)
      OK# a
a Addr#
s Int#
n -> do
        let offset :: Int#
offset = Addr# -> Addr# -> Int#
minusAddr# Addr#
s Addr#
buf
        Result e a -> IO (Result e a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Int -> ByteString -> Result e a
forall e a. a -> Int -> ByteString -> Result e a
OK a
a (Int# -> Int
I# Int#
n) (Int -> ByteString -> ByteString
B.drop (Int# -> Int
I# Int#
offset) ByteString
b))
      Res# e a
Fail# ->
        Result e a -> IO (Result e a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Result e a
forall e a. Result e a
Fail
{-# inlinable runParser #-}

-- | Run a parser on a `String` input. Reminder: @OverloadedStrings@ for `B.ByteString` does not
--   yield a valid UTF-8 encoding! For non-ASCII `B.ByteString` literal input, use `runParserS` or
--   `packUTF8` for testing.
runParserS :: Parser r e a -> r -> Int -> String -> Result e a
runParserS :: Parser r e a -> r -> Int -> String -> Result e a
runParserS Parser r e a
pa r
r !Int
n String
s = Parser r e a -> r -> Int -> ByteString -> Result e a
forall r e a. Parser r e a -> r -> Int -> ByteString -> Result e a
runParser Parser r e a
pa r
r Int
n (String -> ByteString
packUTF8 String
s)

--------------------------------------------------------------------------------

-- | Query the `Int` state.
get :: Parser r e Int
get :: Parser r e Int
get = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Int)
-> Parser r e Int
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> Int -> Addr# -> Int# -> Res# e Int
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Int# -> Int
I# Int#
n) Addr#
s Int#
n
{-# inline get #-}

-- | Write the `Int` state.
put :: Int -> Parser r e ()
put :: Int -> Parser r e ()
put (I# Int#
n) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
_ -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
{-# inline put #-}

-- | Modify the `Int` state.
modify :: (Int -> Int) -> Parser r e ()
modify :: (Int -> Int) -> Parser r e ()
modify Int -> Int
f = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Int -> Int
f (Int# -> Int
I# Int#
n) of
    I# Int#
n -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
{-# inline modify #-}

-- | Query the environment.
ask :: Parser r e r
ask :: Parser r e r
ask = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e r)
-> Parser r e r
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> r -> Addr# -> Int# -> Res# e r
forall a e. a -> Addr# -> Int# -> Res# e a
OK# r
r Addr#
s Int#
n
{-# inline ask #-}

-- | Run a parser in a modified environment.
local :: (r -> r) -> Parser r e a -> Parser r e a
local :: (r -> r) -> Parser r e a -> Parser r e a
local r -> r
f (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
g) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> let !r' :: r
r' = r -> r
f r
r in ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
g ForeignPtrContents
fp r
r' Addr#
eob Addr#
s Int#
n
{-# inline local #-}

--------------------------------------------------------------------------------

-- | The failing parser. By default, parser choice `(<|>)` arbitrarily backtracks
--   on parser failure.
empty :: Parser r e a
empty :: Parser r e a
empty = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> Res# e a
forall e a. Res# e a
Fail#
{-# inline empty #-}

-- | Throw a parsing error. By default, parser choice `(<|>)` can't backtrack
--   on parser error. Use `try` to convert an error to a recoverable failure.
err :: e -> Parser r e a
err :: e -> Parser r e a
err e
e = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> e -> Res# e a
forall e a. e -> Res# e a
Err# e
e
{-# inline err #-}

-- | Save the parsing state, then run a parser, then restore the state.
lookahead :: Parser r e a -> Parser r e a
lookahead :: Parser r e a -> Parser r e a
lookahead (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
_ Int#
_ -> a -> Addr# -> Int# -> Res# e a
forall a e. a -> Addr# -> Int# -> Res# e a
OK# a
a Addr#
s Int#
n
    Res# e a
x         -> Res# e a
x
{-# inline lookahead #-}

-- | Convert a parsing failure to a success.
fails :: Parser r e a -> Parser r e ()
fails :: Parser r e a -> Parser r e ()
fails (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
_ Addr#
_ Int#
_ -> Res# e ()
forall e a. Res# e a
Fail#
    Res# e a
Fail#     -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
    Err# e
e    -> e -> Res# e ()
forall e a. e -> Res# e a
Err# e
e
{-# inline fails #-}

-- | Convert a parsing error into failure.
try :: Parser r e a -> Parser r e a
try :: Parser r e a -> Parser r e a
try (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  Err# e
_ -> Res# e a
forall e a. Res# e a
Fail#
  Res# e a
x      -> Res# e a
x
{-# inline try #-}

-- | Convert a parsing failure to a `Maybe`. If possible, use `withOption` instead.
optional :: Parser r e a -> Parser r e (Maybe a)
optional :: Parser r e a -> Parser r e (Maybe a)
optional Parser r e a
p = (a -> Maybe a
forall k1. k1 -> Maybe k1
Just (a -> Maybe a) -> Parser r e a -> Parser r e (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser r e a
p) Parser r e (Maybe a)
-> Parser r e (Maybe a) -> Parser r e (Maybe a)
forall r e a. Parser r e a -> Parser r e a -> Parser r e a
<|> Maybe a -> Parser r e (Maybe a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall k1. Maybe k1
Nothing
{-# inline optional #-}

-- | Convert a parsing failure to a `()`.
optional_ :: Parser r e a -> Parser r e ()
optional_ :: Parser r e a -> Parser r e ()
optional_ Parser r e a
p = (() () -> Parser r e a -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e a
p) Parser r e () -> Parser r e () -> Parser r e ()
forall r e a. Parser r e a -> Parser r e a -> Parser r e a
<|> () -> Parser r e ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
{-# inline optional_ #-}

-- | CPS'd version of `optional`. This is usually more efficient, since it gets rid of the
--   extra `Maybe` allocation.
withOption :: Parser r e a -> (a -> Parser r e b) -> Parser r e b -> Parser r e b
withOption :: Parser r e a -> (a -> Parser r e b) -> Parser r e b -> Parser r e b
withOption (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) a -> Parser r e b
just (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
nothing) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# a
a Addr#
s Int#
n -> Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (a -> Parser r e b
just a
a) ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
  Res# e a
Fail#     -> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
nothing ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
  Err# e
e    -> e -> Res# e b
forall e a. e -> Res# e a
Err# e
e
{-# inline withOption #-}

-- | Convert a parsing failure to an error.
cut :: Parser r e a -> e -> Parser r e a
cut :: Parser r e a -> e -> Parser r e a
cut (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) e
e = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  Res# e a
Fail# -> e -> Res# e a
forall e a. e -> Res# e a
Err# e
e
  Res# e a
x     -> Res# e a
x
{-# inline cut #-}

-- | Run the parser, if we get a failure, throw the given error, but if we get an error, merge the
--   inner and the newly given errors using the @e -> e -> e@ function. This can be useful for
--   implementing parsing errors which may propagate hints or accummulate contextual information.
cutting :: Parser r e a -> e -> (e -> e -> e) -> Parser r e a
cutting :: Parser r e a -> e -> (e -> e -> e) -> Parser r e a
cutting (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) e
e e -> e -> e
merge = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  Res# e a
Fail#   -> e -> Res# e a
forall e a. e -> Res# e a
Err# e
e
  Err# e
e' -> let !e'' :: e
e'' = e -> e -> e
merge e
e' e
e in e -> Res# e a
forall e a. e -> Res# e a
Err# e
e''
  Res# e a
x       -> Res# e a
x
{-# inline cutting #-}

--------------------------------------------------------------------------------


-- | Succeed if the input is empty.
eof :: Parser r e ()
eof :: Parser r e ()
eof = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
s of
  Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
  Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline eof #-}

-- | Read the given number of bytes as a 'ByteString'.
--
-- Throws a runtime error if given a negative integer.
takeBs :: Int -> Parser r e B.ByteString
takeBs :: Int -> Parser r e ByteString
takeBs (I# Int#
n#) = (ForeignPtrContents
 -> r -> Addr# -> Addr# -> Int# -> Res# e ByteString)
-> Parser r e ByteString
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case Int#
n# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
s of
  Int#
1# -> -- have to runtime check for negative values, because they cause a hang
    case Int#
n# Int# -> Int# -> Int#
>=# Int#
0# of
      Int#
1# -> ByteString -> Addr# -> Int# -> Res# e ByteString
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (ForeignPtr Word8 -> Int -> Int -> ByteString
B.PS (Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
s ForeignPtrContents
fp) Int
0 (Int# -> Int
I# Int#
n#)) (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
n#) Int#
n
      Int#
_  -> String -> Res# e ByteString
forall a. HasCallStack => String -> a
error String
"FlatParse.Basic.take: negative integer"
  Int#
_  -> Res# e ByteString
forall e a. Res# e a
Fail#
{-# inline takeBs #-}

-- | Consume the rest of the input. May return the empty bytestring.
takeRestBs :: Parser r e B.ByteString
takeRestBs :: Parser r e ByteString
takeRestBs = (ForeignPtrContents
 -> r -> Addr# -> Addr# -> Int# -> Res# e ByteString)
-> Parser r e ByteString
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  let n# :: Int#
n# = Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
s
  in  ByteString -> Addr# -> Int# -> Res# e ByteString
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (ForeignPtr Word8 -> Int -> Int -> ByteString
B.PS (Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
s ForeignPtrContents
fp) Int
0 (Int# -> Int
I# Int#
n#)) Addr#
eob Int#
n
{-# inline takeRestBs #-}

-- | Parse a UTF-8 character literal. This is a template function, you can use it as
--   @$(char \'x\')@, for example, and the splice in this case has type @Parser r e ()@.
char :: Char -> Q Exp
char :: Char -> Q Exp
char Char
c = String -> Q Exp
string [Char
c]

-- | Read a byte.
byte :: Word8 -> Parser r e ()
byte :: Word8 -> Parser r e ()
byte Word8
w = Int -> Parser r e ()
forall r e. Int -> Parser r e ()
ensureBytes# Int
1 Parser r e () -> Parser r e () -> Parser r e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word8 -> Parser r e ()
forall r e. Word8 -> Parser r e ()
scan8# Word8
w
{-# inline byte #-}

-- | Read a sequence of bytes. This is a template function, you can use it as @$(bytes [3, 4, 5])@,
--   for example, and the splice has type @Parser r e ()@.
bytes :: [Word] -> Q Exp
bytes :: [Word] -> Q Exp
bytes [Word]
bytes = do
  let !len :: Int
len = [Word] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Word]
bytes
  [| ensureBytes# len >> $(scanBytes# bytes) |]

-- | Parse a UTF-8 string literal. This is a template function, you can use it as @$(string "foo")@,
--   for example, and the splice has type @Parser r e ()@.
string :: String -> Q Exp
string :: String -> Q Exp
string String
str = [Word] -> Q Exp
bytes (String -> [Word]
strToBytes String
str)

{-|
This is a template function which makes it possible to branch on a collection of string literals in
an efficient way. By using `switch`, such branching is compiled to a trie of primitive parsing
operations, which has optimized control flow, vectorized reads and grouped checking for needed input
bytes.

The syntax is slightly magical, it overloads the usual @case@ expression. An example:

@
    $(switch [| case _ of
        "foo" -> pure True
        "bar" -> pure False |])
@

The underscore is mandatory in @case _ of@. Each branch must be a string literal, but optionally
we may have a default case, like in

@
    $(switch [| case _ of
        "foo" -> pure 10
        "bar" -> pure 20
        _     -> pure 30 |])
@

All case right hand sides must be parsers with the same type. That type is also the type
of the whole `switch` expression.

A `switch` has longest match semantics, and the order of cases does not matter, except for
the default case, which may only appear as the last case.

If a `switch` does not have a default case, and no case matches the input, then it returns with
failure, \without\ having consumed any input. A fallthrough to the default case also does not
consume any input.
-}
switch :: Q Exp -> Q Exp
switch :: Q Exp -> Q Exp
switch = Maybe (Q Exp) -> Q Exp -> Q Exp
switchWithPost Maybe (Q Exp)
forall k1. Maybe k1
Nothing

{-|
Switch expression with an optional first argument for performing a post-processing action after
every successful branch matching. For example, if we have @ws :: Parser r e ()@ for a
whitespace parser, we might want to consume whitespace after matching on any of the switch
cases. For that case, we can define a "lexeme" version of `switch` as follows.

@
  switch' :: Q Exp -> Q Exp
  switch' = switchWithPost (Just [| ws |])
@

Note that this @switch'@ function cannot be used in the same module it's defined in, because of the
stage restriction of Template Haskell.
-}
switchWithPost :: Maybe (Q Exp) -> Q Exp -> Q Exp
switchWithPost :: Maybe (Q Exp) -> Q Exp -> Q Exp
switchWithPost Maybe (Q Exp)
postAction Q Exp
exp = do
  !Maybe Exp
postAction <- Maybe (Q Exp) -> Q (Maybe Exp)
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence Maybe (Q Exp)
postAction
  (![(String, Exp)]
cases, !Maybe Exp
fallback) <- Q Exp -> Q ([(String, Exp)], Maybe Exp)
parseSwitch Q Exp
exp
  (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int)) -> Q Exp
genTrie ((Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int)) -> Q Exp)
-> (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int))
-> Q Exp
forall a b. (a -> b) -> a -> b
$! Maybe Exp
-> [(String, Exp)]
-> Maybe Exp
-> (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int))
genSwitchTrie' Maybe Exp
postAction [(String, Exp)]
cases Maybe Exp
fallback

-- | Version of `switchWithPost` without syntactic sugar. The second argument is the
--   list of cases, the third is the default case.
rawSwitchWithPost :: Maybe (Q Exp) -> [(String, Q Exp)] -> Maybe (Q Exp) -> Q Exp
rawSwitchWithPost :: Maybe (Q Exp) -> [(String, Q Exp)] -> Maybe (Q Exp) -> Q Exp
rawSwitchWithPost Maybe (Q Exp)
postAction [(String, Q Exp)]
cases Maybe (Q Exp)
fallback = do
  !Maybe Exp
postAction <- Maybe (Q Exp) -> Q (Maybe Exp)
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence Maybe (Q Exp)
postAction
  ![(String, Exp)]
cases <- [(String, Q Exp)]
-> ((String, Q Exp) -> Q (String, Exp)) -> Q [(String, Exp)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(String, Q Exp)]
cases \(String
str, Q Exp
rhs) -> (String
str,) (Exp -> (String, Exp)) -> Q Exp -> Q (String, Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Q Exp
rhs
  !Maybe Exp
fallback <- Maybe (Q Exp) -> Q (Maybe Exp)
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence Maybe (Q Exp)
fallback
  (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int)) -> Q Exp
genTrie ((Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int)) -> Q Exp)
-> (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int))
-> Q Exp
forall a b. (a -> b) -> a -> b
$! Maybe Exp
-> [(String, Exp)]
-> Maybe Exp
-> (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int))
genSwitchTrie' Maybe Exp
postAction [(String, Exp)]
cases Maybe Exp
fallback

-- | Parse a UTF-8 `Char` for which a predicate holds.
satisfy :: (Char -> Bool) -> Parser r e Char
satisfy :: (Char -> Bool) -> Parser r e Char
satisfy Char -> Bool
f = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Char)
-> Parser r e Char
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case Parser r Any Char
-> ForeignPtrContents
-> r
-> Addr#
-> Addr#
-> Int#
-> Res# Any Char
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r Any Char
forall r e. Parser r e Char
anyChar ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# Char
c Addr#
s Int#
n | Char -> Bool
f Char
c -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# Char
c Addr#
s Int#
n
  Res# Any Char
_               -> Res# e Char
forall e a. Res# e a
Fail#
{-#  inline satisfy #-}

-- | Skip a UTF-8 `Char` for which a predicate holds.
satisfy_ :: (Char -> Bool) -> Parser r e ()
satisfy_ :: (Char -> Bool) -> Parser r e ()
satisfy_ Char -> Bool
f = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case Parser r Any Char
-> ForeignPtrContents
-> r
-> Addr#
-> Addr#
-> Int#
-> Res# Any Char
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r Any Char
forall r e. Parser r e Char
anyChar ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# Char
c Addr#
s Int#
n | Char -> Bool
f Char
c -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
  Res# Any Char
_               -> Res# e ()
forall e a. Res# e a
Fail#
{-#  inline satisfy_ #-}

-- | Parse an ASCII `Char` for which a predicate holds. Assumption: the predicate must only return
--   `True` for ASCII-range characters. Otherwise this function might read a 128-255 range byte,
--   thereby breaking UTF-8 decoding.
satisfyASCII :: (Char -> Bool) -> Parser r e Char
satisfyASCII :: (Char -> Bool) -> Parser r e Char
satisfyASCII Char -> Bool
f = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Char)
-> Parser r e Char
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
s of
  Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Char#
derefChar8# Addr#
s of
    Char#
c1 | Char -> Bool
f (Char# -> Char
C# Char#
c1) -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# Char#
c1) (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
1#) Int#
n
       | Bool
otherwise -> Res# e Char
forall e a. Res# e a
Fail#
{-#  inline satisfyASCII #-}

-- | Skip an ASCII `Char` for which a predicate holds.  Assumption: the
--   predicate must only return `True` for ASCII-range characters.
satisfyASCII_ :: (Char -> Bool) -> Parser r e ()
satisfyASCII_ :: (Char -> Bool) -> Parser r e ()
satisfyASCII_ Char -> Bool
f = () () -> Parser r e Char -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Char -> Bool) -> Parser r e Char
forall r e. (Char -> Bool) -> Parser r e Char
satisfyASCII Char -> Bool
f
{-# inline satisfyASCII_ #-}

-- | This is a variant of `satisfy` which allows more optimization. We can pick four testing
--   functions for the four cases for the possible number of bytes in the UTF-8 character. So in
--   @fusedSatisfy f1 f2 f3 f4@, if we read a one-byte character, the result is scrutinized with
--   @f1@, for two-bytes, with @f2@, and so on. This can result in dramatic lexing speedups.
--
--   For example, if we want to accept any letter, the naive solution would be to use
--   `Data.Char.isLetter`, but this accesses a large lookup table of Unicode character classes. We
--   can do better with @fusedSatisfy isLatinLetter isLetter isLetter isLetter@, since here the
--   `isLatinLetter` is inlined into the UTF-8 decoding, and it probably handles a great majority of
--   all cases without accessing the character table.
fusedSatisfy :: (Char -> Bool) -> (Char -> Bool) -> (Char -> Bool) -> (Char -> Bool) -> Parser r e Char
fusedSatisfy :: (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> Parser r e Char
fusedSatisfy Char -> Bool
f1 Char -> Bool
f2 Char -> Bool
f3 Char -> Bool
f4 = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Char)
-> Parser r e Char
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
buf of
  Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Char#
derefChar8# Addr#
buf of
    Char#
c1 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\x7F'# of
      Int#
1# | Char -> Bool
f1 (Char# -> Char
C# Char#
c1) -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# Char#
c1) (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) Int#
n
         | Bool
otherwise  -> Res# e Char
forall e a. Res# e a
Fail#
      Int#
_  -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) of
        Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
        Int#
_ -> case Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
buf Int#
1# of
          Char#
c2 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\xDF'# of
            Int#
1# ->
              let resc :: Char
resc = Char# -> Char
C# (Int# -> Char#
chr# (((Char# -> Int#
ord# Char#
c1 Int# -> Int# -> Int#
-# Int#
0xC0#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
6#) Int# -> Int# -> Int#
`orI#`
                                   (Char# -> Int#
ord# Char#
c2 Int# -> Int# -> Int#
-# Int#
0x80#)))
              in case Char -> Bool
f2 Char
resc of
                   Bool
True -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# Char
resc (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#) Int#
n
                   Bool
_    -> Res# e Char
forall e a. Res# e a
Fail#
            Int#
_ -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#) of
              Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
              Int#
_  -> case Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
buf Int#
2# of
                Char#
c3 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\xEF'# of
                  Int#
1# ->
                    let resc :: Char
resc = Char# -> Char
C# (Int# -> Char#
chr# (((Char# -> Int#
ord# Char#
c1 Int# -> Int# -> Int#
-# Int#
0xE0#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
12#) Int# -> Int# -> Int#
`orI#`
                                         ((Char# -> Int#
ord# Char#
c2 Int# -> Int# -> Int#
-# Int#
0x80#) Int# -> Int# -> Int#
`uncheckedIShiftL#`  Int#
6#) Int# -> Int# -> Int#
`orI#`
                                         (Char# -> Int#
ord# Char#
c3 Int# -> Int# -> Int#
-# Int#
0x80#)))
                    in case Char -> Bool
f3 Char
resc of
                         Bool
True -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# Char
resc (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
3#) Int#
n
                         Bool
_    -> Res# e Char
forall e a. Res# e a
Fail#
                  Int#
_ -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
3#) of
                    Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
                    Int#
_  -> case Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
buf Int#
3# of
                      Char#
c4 ->
                        let resc :: Char
resc = Char# -> Char
C# (Int# -> Char#
chr# (((Char# -> Int#
ord# Char#
c1 Int# -> Int# -> Int#
-# Int#
0xF0#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
18#) Int# -> Int# -> Int#
`orI#`
                                             ((Char# -> Int#
ord# Char#
c2 Int# -> Int# -> Int#
-# Int#
0x80#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
12#) Int# -> Int# -> Int#
`orI#`
                                             ((Char# -> Int#
ord# Char#
c3 Int# -> Int# -> Int#
-# Int#
0x80#) Int# -> Int# -> Int#
`uncheckedIShiftL#`  Int#
6#) Int# -> Int# -> Int#
`orI#`
                                              (Char# -> Int#
ord# Char#
c4 Int# -> Int# -> Int#
-# Int#
0x80#)))
                        in case Char -> Bool
f4 Char
resc of
                             Bool
True -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# Char
resc (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
4#) Int#
n
                             Bool
_    -> Res# e Char
forall e a. Res# e a
Fail#
{-# inline fusedSatisfy #-}

-- | Skipping variant of `fusedSatisfy`.
fusedSatisfy_ :: (Char -> Bool) -> (Char -> Bool) -> (Char -> Bool) -> (Char -> Bool) -> Parser r e ()
fusedSatisfy_ :: (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> Parser r e ()
fusedSatisfy_ Char -> Bool
f1 Char -> Bool
f2 Char -> Bool
f3 Char -> Bool
f4 = () () -> Parser r e Char -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> Parser r e Char
forall r e.
(Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> (Char -> Bool)
-> Parser r e Char
fusedSatisfy Char -> Bool
f1 Char -> Bool
f2 Char -> Bool
f3 Char -> Bool
f4
{-# inline fusedSatisfy_ #-}

-- | Parse any UTF-8-encoded `Char`.
anyChar :: Parser r e Char
anyChar :: Parser r e Char
anyChar = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Char)
-> Parser r e Char
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
buf of
  Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Char#
derefChar8# Addr#
buf of
    Char#
c1 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\x7F'# of
      Int#
1# -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# Char#
c1) (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) Int#
n
      Int#
_  -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) of
        Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
        Int#
_ -> case Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
buf Int#
1# of
          Char#
c2 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\xDF'# of
            Int#
1# ->
              let resc :: Int#
resc = ((Char# -> Int#
ord# Char#
c1 Int# -> Int# -> Int#
-# Int#
0xC0#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
6#) Int# -> Int# -> Int#
`orI#`
                          (Char# -> Int#
ord# Char#
c2 Int# -> Int# -> Int#
-# Int#
0x80#)
              in Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# (Int# -> Char#
chr# Int#
resc)) (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#) Int#
n
            Int#
_ -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#) of
              Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
              Int#
_  -> case Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
buf Int#
2# of
                Char#
c3 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\xEF'# of
                  Int#
1# ->
                    let resc :: Int#
resc = ((Char# -> Int#
ord# Char#
c1 Int# -> Int# -> Int#
-# Int#
0xE0#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
12#) Int# -> Int# -> Int#
`orI#`
                               ((Char# -> Int#
ord# Char#
c2 Int# -> Int# -> Int#
-# Int#
0x80#) Int# -> Int# -> Int#
`uncheckedIShiftL#`  Int#
6#) Int# -> Int# -> Int#
`orI#`
                                (Char# -> Int#
ord# Char#
c3 Int# -> Int# -> Int#
-# Int#
0x80#)
                    in Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# (Int# -> Char#
chr# Int#
resc)) (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
3#) Int#
n
                  Int#
_ -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
3#) of
                    Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
                    Int#
_  -> case Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
buf Int#
3# of
                      Char#
c4 ->
                        let resc :: Int#
resc = ((Char# -> Int#
ord# Char#
c1 Int# -> Int# -> Int#
-# Int#
0xF0#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
18#) Int# -> Int# -> Int#
`orI#`
                                   ((Char# -> Int#
ord# Char#
c2 Int# -> Int# -> Int#
-# Int#
0x80#) Int# -> Int# -> Int#
`uncheckedIShiftL#` Int#
12#) Int# -> Int# -> Int#
`orI#`
                                   ((Char# -> Int#
ord# Char#
c3 Int# -> Int# -> Int#
-# Int#
0x80#) Int# -> Int# -> Int#
`uncheckedIShiftL#`  Int#
6#) Int# -> Int# -> Int#
`orI#`
                                    (Char# -> Int#
ord# Char#
c4 Int# -> Int# -> Int#
-# Int#
0x80#)
                        in Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# (Int# -> Char#
chr# Int#
resc)) (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
4#) Int#
n
{-# inline anyChar #-}

-- | Skip any UTF-8-encoded `Char`.
anyChar_ :: Parser r e ()
anyChar_ :: Parser r e ()
anyChar_ = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
buf of
  Int#
1# -> Res# e ()
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Char#
derefChar8# Addr#
buf of
    Char#
c1 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\x7F'# of
      Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) Int#
n
      Int#
_  ->
        let buf' :: Addr#
buf' =
              case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\xDF'# of
                Int#
1# -> Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#
                Int#
_  -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\xEF'# of
                    Int#
1# -> Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
3#
                    Int#
_ ->  Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
4#
        in case Addr# -> Addr# -> Int#
leAddr# Addr#
buf' Addr#
eob of
             Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
buf' Int#
n
             Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline anyChar_ #-}


-- | Parse any `Char` in the ASCII range, fail if the next input character is not in the range.
--   This is more efficient than `anyChar` if we are only working with ASCII.
anyCharASCII :: Parser r e Char
anyCharASCII :: Parser r e Char
anyCharASCII = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Char)
-> Parser r e Char
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
buf of
  Int#
1# -> Res# e Char
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Char#
derefChar8# Addr#
buf of
    Char#
c1 -> case Char#
c1 Char# -> Char# -> Int#
`leChar#` Char#
'\x7F'# of
      Int#
1# -> Char -> Addr# -> Int# -> Res# e Char
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Char# -> Char
C# Char#
c1) (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) Int#
n
      Int#
_  -> Res# e Char
forall e a. Res# e a
Fail#
{-# inline anyCharASCII #-}

-- | Skip any `Char` in the ASCII range. More efficient than `anyChar_` if we're working only with
--   ASCII.
anyCharASCII_ :: Parser r e ()
anyCharASCII_ :: Parser r e ()
anyCharASCII_ = () () -> Parser r e Char -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e Char
forall r e. Parser r e Char
anyCharASCII
{-# inline anyCharASCII_ #-}

-- | Read an `Int` from the input, as a non-empty digit sequence. The `Int` may
--   overflow in the result.
readInt :: Parser r e Int
readInt :: Parser r e Int
readInt = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Int)
-> Parser r e Int
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n -> case Addr# -> Addr# -> (# (# #) | (# Int#, Addr# #) #)
FlatParse.Internal.readInt Addr#
eob Addr#
s of
  (# (##) | #)        -> Res# e Int
forall e a. Res# e a
Fail#
  (# | (# Int#
i, Addr#
s' #) #) -> Int -> Addr# -> Int# -> Res# e Int
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Int# -> Int
I# Int#
i) Addr#
s' Int#
n
{-# inline readInt #-}

-- | Read an `Integer` from the input, as a non-empty digit sequence.
readInteger :: Parser r e Integer
readInteger :: Parser r e Integer
readInteger = (ForeignPtrContents
 -> r -> Addr# -> Addr# -> Int# -> Res# e Integer)
-> Parser r e Integer
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents
-> Addr# -> Addr# -> (# (# #) | (# Integer, Addr# #) #)
FlatParse.Internal.readInteger ForeignPtrContents
fp Addr#
eob Addr#
s of
  (# (##) | #)        -> Res# e Integer
forall e a. Res# e a
Fail#
  (# | (# Integer
i, Addr#
s' #) #) -> Integer -> Addr# -> Int# -> Res# e Integer
forall a e. a -> Addr# -> Int# -> Res# e a
OK# Integer
i Addr#
s' Int#
n
{-# inline readInteger #-}


--------------------------------------------------------------------------------

-- | Choose between two parsers. If the first parser fails, try the second one, but if the first one
--   throws an error, propagate the error.
infixr 6 <|>
(<|>) :: Parser r e a -> Parser r e a -> Parser r e a
<|> :: Parser r e a -> Parser r e a -> Parser r e a
(<|>) (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
g) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    Res# e a
Fail# -> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
g ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
    Res# e a
x     -> Res# e a
x
{-# inline (<|>) #-}

-- | Branch on a parser: if the first argument succeeds, continue with the second, else with the third.
--   This can produce slightly more efficient code than `(<|>)`. Moreover, `ḃranch` does not
--   backtrack from the true/false cases.
branch :: Parser r e a -> Parser r e b -> Parser r e b -> Parser r e b
branch :: Parser r e a -> Parser r e b -> Parser r e b -> Parser r e b
branch Parser r e a
pa Parser r e b
pt Parser r e b
pf = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e a
pa ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# a
_ Addr#
s Int#
n -> Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e b
pt ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
  Res# e a
Fail#     -> Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e b
pf ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
  Err# e
e    -> e -> Res# e b
forall e a. e -> Res# e a
Err# e
e
{-# inline branch #-}

-- | An analogue of the list `foldl` function: first parse a @b@, then parse zero or more @a@-s,
--   and combine the results in a left-nested way by the @b -> a -> b@ function. Note: this is not
--   the usual `chainl` function from the parsec libraries!
chainl :: (b -> a -> b) -> Parser r e b -> Parser r e a -> Parser r e b
chainl :: (b -> a -> b) -> Parser r e b -> Parser r e a -> Parser r e b
chainl b -> a -> b
f Parser r e b
start Parser r e a
elem = Parser r e b
start Parser r e b -> (b -> Parser r e b) -> Parser r e b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= b -> Parser r e b
go where
  go :: b -> Parser r e b
go b
b = do {!a
a <- Parser r e a
elem; b -> Parser r e b
go (b -> Parser r e b) -> b -> Parser r e b
forall a b. (a -> b) -> a -> b
$! b -> a -> b
f b
b a
a} Parser r e b -> Parser r e b -> Parser r e b
forall r e a. Parser r e a -> Parser r e a -> Parser r e a
<|> b -> Parser r e b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
b
{-# inline chainl #-}

-- | An analogue of the list `foldr` function: parse zero or more @a@-s, terminated by a @b@, and
--   combine the results in a right-nested way using the @a -> b -> b@ function. Note: this is not
--   the usual `chainr` function from the parsec libraries!
chainr :: (a -> b -> b) -> Parser r e a -> Parser r e b -> Parser r e b
chainr :: (a -> b -> b) -> Parser r e a -> Parser r e b -> Parser r e b
chainr a -> b -> b
f (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
elem) (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
end) = Parser r e b
go where
  go :: Parser r e b
go = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
elem ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n -> case Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e b
go ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
      OK# b
b Addr#
s Int#
n -> let !b' :: b
b' = a -> b -> b
f a
a b
b in b -> Addr# -> Int# -> Res# e b
forall a e. a -> Addr# -> Int# -> Res# e a
OK# b
b' Addr#
s Int#
n
      Res# e b
x         -> Res# e b
x
    Res# e a
Fail# -> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
end ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
    Err# e
e -> e -> Res# e b
forall e a. e -> Res# e a
Err# e
e
{-# inline chainr #-}

-- | Run a parser zero or more times, collect the results in a list. Note: for optimal performance,
--   try to avoid this. Often it is possible to get rid of the intermediate list by using a
--   combinator or a custom parser.
many :: Parser r e a -> Parser r e [a]
many :: Parser r e a -> Parser r e [a]
many (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = Parser r e [a]
go where
  go :: Parser r e [a]
go = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e [a])
-> Parser r e [a]
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n -> case Parser r e [a]
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e [a]
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e [a]
go ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
                   OK# [a]
as Addr#
s Int#
n -> [a] -> Addr# -> Int# -> Res# e [a]
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (a
aa -> [a] -> [a]
forall k1. k1 -> [k1] -> [k1]
:[a]
as) Addr#
s Int#
n
                   Res# e [a]
x          -> Res# e [a]
x
    Res# e a
Fail#  -> [a] -> Addr# -> Int# -> Res# e [a]
forall a e. a -> Addr# -> Int# -> Res# e a
OK# [] Addr#
s Int#
n
    Err# e
e -> e -> Res# e [a]
forall e a. e -> Res# e a
Err# e
e
{-# inline many #-}

-- | Skip a parser zero or more times.
many_ :: Parser r e a -> Parser r e ()
many_ :: Parser r e a -> Parser r e ()
many_ (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = Parser r e ()
go where
  go :: Parser r e ()
go = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
    OK# a
a Addr#
s Int#
n -> Parser r e ()
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ()
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e ()
go ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n
    Res# e a
Fail#     -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
    Err# e
e    -> e -> Res# e ()
forall e a. e -> Res# e a
Err# e
e
{-# inline many_ #-}

-- | Run a parser one or more times, collect the results in a list. Note: for optimal performance,
--   try to avoid this. Often it is possible to get rid of the intermediate list by using a
--   combinator or a custom parser.
some :: Parser r e a -> Parser r e [a]
some :: Parser r e a -> Parser r e [a]
some Parser r e a
p = (:) (a -> [a] -> [a]) -> Parser r e a -> Parser r e ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser r e a
p Parser r e ([a] -> [a]) -> Parser r e [a] -> Parser r e [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser r e a -> Parser r e [a]
forall r e a. Parser r e a -> Parser r e [a]
many Parser r e a
p
{-# inline some #-}

-- | Skip a parser one or more times.
some_ :: Parser r e a -> Parser r e ()
some_ :: Parser r e a -> Parser r e ()
some_ Parser r e a
pa = Parser r e a
pa Parser r e a -> Parser r e () -> Parser r e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser r e a -> Parser r e ()
forall r e a. Parser r e a -> Parser r e ()
many_ Parser r e a
pa
{-# inline some_ #-}

-- | Succeed if the first parser succeeds and the second one fails. The parsing
--   state is restored to the point of the first argument's success.
notFollowedBy :: Parser r e a -> Parser r e b -> Parser r e a
notFollowedBy :: Parser r e a -> Parser r e b -> Parser r e a
notFollowedBy Parser r e a
p1 Parser r e b
p2 = Parser r e a
p1 Parser r e a -> Parser r e () -> Parser r e a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser r e () -> Parser r e ()
forall r e a. Parser r e a -> Parser r e a
lookahead (Parser r e b -> Parser r e ()
forall r e a. Parser r e a -> Parser r e ()
fails Parser r e b
p2)
{-# inline notFollowedBy #-}

-- | @isolate n p@ runs the parser @p@ isolated to the next @n@ bytes. All
--   isolated bytes must be consumed.
--
-- Throws a runtime error if given a negative integer.
isolate :: Int -> Parser r e a -> Parser r e a
isolate :: Int -> Parser r e a -> Parser r e a
isolate (I# Int#
n#) Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  let s' :: Addr#
s' = Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
n#
  in  case Int#
n# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
s of
        Int#
1# -> case Int#
n# Int# -> Int# -> Int#
>=# Int#
0# of
          Int#
1# -> case Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# Parser r e a
p ForeignPtrContents
fp r
r Addr#
s' Addr#
s Int#
n of
            OK# a
a Addr#
s'' Int#
n' -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
s' Addr#
s'' of
              Int#
1# -> a -> Addr# -> Int# -> Res# e a
forall a e. a -> Addr# -> Int# -> Res# e a
OK# a
a Addr#
s'' Int#
n'
              Int#
_  -> Res# e a
forall e a. Res# e a
Fail# -- isolated segment wasn't fully consumed
            Res# e a
Fail#     -> Res# e a
forall e a. Res# e a
Fail#
            Err# e
e    -> e -> Res# e a
forall e a. e -> Res# e a
Err# e
e
          Int#
_  -> String -> Res# e a
forall a. HasCallStack => String -> a
error String
"FlatParse.Basic.isolate: negative integer"
        Int#
_  -> Res# e a
forall e a. Res# e a
Fail# -- you tried to isolate more than we have left
{-# inline isolate #-}

--------------------------------------------------------------------------------

-- | Get the current position in the input.
getPos :: Parser r e Pos
getPos :: Parser r e Pos
getPos = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Pos)
-> Parser r e Pos
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> Pos -> Addr# -> Int# -> Res# e Pos
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Addr# -> Addr# -> Pos
addrToPos# Addr#
eob Addr#
s) Addr#
s Int#
n
{-# inline getPos #-}

-- | Set the input position. Warning: this can result in crashes if the position points outside the
--   current buffer. It is always safe to `setPos` values which came from `getPos` with the current
--   input.
setPos :: Pos -> Parser r e ()
setPos :: Pos -> Parser r e ()
setPos Pos
s = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
_ Int#
n -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Pos -> Addr#
posToAddr# Addr#
eob Pos
s) Int#
n
{-# inline setPos #-}

-- | The end of the input.
endPos :: Pos
endPos :: Pos
endPos = Int -> Pos
Pos Int
0
{-# inline endPos #-}


-- | Return the consumed span of a parser. Use `withSpan` if possible for better efficiency.
spanOf :: Parser r e a -> Parser r e Span
spanOf :: Parser r e a -> Parser r e Span
spanOf (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Span)
-> Parser r e Span
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# a
a Addr#
s' Int#
n -> Span -> Addr# -> Int# -> Res# e Span
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Pos -> Pos -> Span
Span (Addr# -> Addr# -> Pos
addrToPos# Addr#
eob Addr#
s) (Addr# -> Addr# -> Pos
addrToPos# Addr#
eob Addr#
s')) Addr#
s' Int#
n
  Res# e a
x          -> Res# e a -> Res# e Span
unsafeCoerce# Res# e a
x
{-# inline spanOf #-}

-- | Bind the result together with the span of the result. CPS'd version of `spanOf`
--   for better unboxing.
withSpan :: Parser r e a -> (a -> Span -> Parser r e b) -> Parser r e b
withSpan :: Parser r e a -> (a -> Span -> Parser r e b) -> Parser r e b
withSpan (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) a -> Span -> Parser r e b
g = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# a
a Addr#
s' Int#
n -> Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (a -> Span -> Parser r e b
g a
a (Pos -> Pos -> Span
Span (Addr# -> Addr# -> Pos
addrToPos# Addr#
eob Addr#
s) (Addr# -> Addr# -> Pos
addrToPos# Addr#
eob Addr#
s'))) ForeignPtrContents
fp r
r Addr#
eob Addr#
s' Int#
n
  Res# e a
x          -> Res# e a -> Res# e b
unsafeCoerce# Res# e a
x
{-# inline withSpan #-}

-- | Return the `B.ByteString` consumed by a parser. Note: it's more efficient to use `spanOf` and
--   `withSpan` instead.
byteStringOf :: Parser r e a -> Parser r e B.ByteString
byteStringOf :: Parser r e a -> Parser r e ByteString
byteStringOf (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = (ForeignPtrContents
 -> r -> Addr# -> Addr# -> Int# -> Res# e ByteString)
-> Parser r e ByteString
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# a
a Addr#
s' Int#
n -> ByteString -> Addr# -> Int# -> Res# e ByteString
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (ForeignPtr Word8 -> Int -> Int -> ByteString
B.PS (Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
s ForeignPtrContents
fp) Int
0 (Int# -> Int
I# (Addr# -> Addr# -> Int#
minusAddr# Addr#
s' Addr#
s))) Addr#
s' Int#
n
  Res# e a
x          -> Res# e a -> Res# e ByteString
unsafeCoerce# Res# e a
x
{-# inline byteStringOf #-}

-- | CPS'd version of `byteStringOf`. Can be more efficient, because the result is more eagerly unboxed
--   by GHC. It's more efficient to use `spanOf` or `withSpan` instead.
withByteString :: Parser r e a -> (a -> B.ByteString -> Parser r e b) -> Parser r e b
withByteString :: Parser r e a -> (a -> ByteString -> Parser r e b) -> Parser r e b
withByteString (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) a -> ByteString -> Parser r e b
g = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b)
-> Parser r e b
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r Addr#
eob Addr#
s Int#
n of
  OK# a
a Addr#
s' Int#
n -> Parser r e b
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e b
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (a -> ByteString -> Parser r e b
g a
a (ForeignPtr Word8 -> Int -> Int -> ByteString
B.PS (Addr# -> ForeignPtrContents -> ForeignPtr Word8
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
s ForeignPtrContents
fp) Int
0 (Int# -> Int
I# (Addr# -> Addr# -> Int#
minusAddr# Addr#
s' Addr#
s)))) ForeignPtrContents
fp r
r Addr#
eob Addr#
s' Int#
n
  Res# e a
x          -> Res# e a -> Res# e b
unsafeCoerce# Res# e a
x
{-# inline withByteString #-}

-- | Create a `B.ByteString` from a `Span`. The result is invalid is the `Span` points
--   outside the current buffer, or if the `Span` start is greater than the end position.
unsafeSpanToByteString :: Span -> Parser r e B.ByteString
unsafeSpanToByteString :: Span -> Parser r e ByteString
unsafeSpanToByteString (Span Pos
l Pos
r) =
  Parser r e ByteString -> Parser r e ByteString
forall r e a. Parser r e a -> Parser r e a
lookahead (Pos -> Parser r e ()
forall r e. Pos -> Parser r e ()
setPos Pos
l Parser r e () -> Parser r e ByteString -> Parser r e ByteString
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser r e () -> Parser r e ByteString
forall r e a. Parser r e a -> Parser r e ByteString
byteStringOf (Pos -> Parser r e ()
forall r e. Pos -> Parser r e ()
setPos Pos
r))
{-# inline unsafeSpanToByteString #-}


-- | Run a parser in a given input span. The input position and the `Int` state is restored after
--   the parser is finished, so `inSpan` does not consume input and has no side effect.  Warning:
--   this operation may crash if the given span points outside the current parsing buffer. It's
--   always safe to use `inSpan` if the span comes from a previous `withSpan` or `spanOf` call on
--   the current input.
inSpan :: Span -> Parser r e a -> Parser r e a
inSpan :: Span -> Parser r e a -> Parser r e a
inSpan (Span Pos
s Pos
eob) (Parser ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob' Addr#
s' Int#
n' ->
  case ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
f ForeignPtrContents
fp r
r (Addr# -> Pos -> Addr#
posToAddr# Addr#
eob' Pos
eob) (Addr# -> Pos -> Addr#
posToAddr# Addr#
eob' Pos
s) Int#
n' of
    OK# a
a Addr#
_ Int#
_ -> a -> Addr# -> Int# -> Res# e a
forall a e. a -> Addr# -> Int# -> Res# e a
OK# a
a Addr#
s' Int#
n'
    Res# e a
x         -> Res# e a -> Res# e a
unsafeCoerce# Res# e a
x
{-# inline inSpan #-}


--------------------------------------------------------------------------------

-- | Parse the rest of the current line as a `String`. Assumes UTF-8 encoding,
--   throws an error if the encoding is invalid.
takeLine :: Parser r e String
takeLine :: Parser r e String
takeLine = Parser r e ()
-> Parser r e String -> Parser r e String -> Parser r e String
forall r e a b.
Parser r e a -> Parser r e b -> Parser r e b -> Parser r e b
branch Parser r e ()
forall r e. Parser r e ()
eof (String -> Parser r e String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"") do
  Char
c <- Parser r e Char
forall r e. Parser r e Char
anyChar
  case Char
c of
    Char
'\n' -> String -> Parser r e String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
""
    Char
_    -> (Char
cChar -> ShowS
forall k1. k1 -> [k1] -> [k1]
:) ShowS -> Parser r e String -> Parser r e String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser r e String
forall r e. Parser r e String
takeLine

-- | Parse the rest of the current line as a `String`, but restore the parsing state.
--   Assumes UTF-8 encoding. This can be used for debugging.
traceLine :: Parser r e String
traceLine :: Parser r e String
traceLine = Parser r e String -> Parser r e String
forall r e a. Parser r e a -> Parser r e a
lookahead Parser r e String
forall r e. Parser r e String
takeLine

-- | Take the rest of the input as a `String`. Assumes UTF-8 encoding.
takeRest :: Parser r e String
takeRest :: Parser r e String
takeRest = Parser r e ()
-> Parser r e String -> Parser r e String -> Parser r e String
forall r e a b.
Parser r e a -> Parser r e b -> Parser r e b -> Parser r e b
branch Parser r e ()
forall r e. Parser r e ()
eof (String -> Parser r e String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"") do
  Char
c <- Parser r e Char
forall r e. Parser r e Char
anyChar
  String
cs <- Parser r e String
forall r e. Parser r e String
takeRest
  String -> Parser r e String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Char
cChar -> ShowS
forall k1. k1 -> [k1] -> [k1]
:String
cs)

-- | Get the rest of the input as a `String`, but restore the parsing state. Assumes UTF-8 encoding.
--   This can be used for debugging.
traceRest :: Parser r e String
traceRest :: Parser r e String
traceRest = Parser r e String -> Parser r e String
forall r e a. Parser r e a -> Parser r e a
lookahead Parser r e String
forall r e. Parser r e String
takeRest

--------------------------------------------------------------------------------

-- | Check that the input has at least the given number of bytes.
ensureBytes# :: Int -> Parser r e ()
ensureBytes# :: Int -> Parser r e ()
ensureBytes# (I# Int#
len) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Int#
len  Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
s of
    Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () Addr#
s Int#
n
    Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline ensureBytes# #-}

-- | Unsafely read a concrete byte from the input. It's not checked that the input has
--   enough bytes.
scan8# :: Word8 -> Parser r e ()
scan8# :: Word8 -> Parser r e ()
scan8# (W8# Word#
c) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Addr# -> Int# -> Word#
indexWord8OffAddr# Addr#
s Int#
0# of
    Word#
c' -> case Word# -> Word# -> Int#
eqWord8'# Word#
c Word#
c' of
      Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
1#) Int#
n
      Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline scan8# #-}

-- | Unsafely read two concrete bytes from the input. It's not checked that the input has
--   enough bytes.
scan16# :: Word16 -> Parser r e ()
scan16# :: Word16 -> Parser r e ()
scan16# (W16# Word#
c) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Addr# -> Int# -> Word#
indexWord16OffAddr# Addr#
s Int#
0# of
    Word#
c' -> case Word# -> Word# -> Int#
eqWord16'# Word#
c Word#
c' of
      Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
2#) Int#
n
      Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline scan16# #-}

-- | Unsafely read four concrete bytes from the input. It's not checked that the input has
--   enough bytes.
scan32# :: Word32 -> Parser r e ()
scan32# :: Word32 -> Parser r e ()
scan32# (W32# Word#
c) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Addr# -> Int# -> Word#
indexWord32OffAddr# Addr#
s Int#
0# of
    Word#
c' -> case Word# -> Word# -> Int#
eqWord32'# Word#
c Word#
c' of
      Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
4#) Int#
n
      Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline scan32# #-}

-- | Unsafely read eight concrete bytes from the input. It's not checked that the input has
--   enough bytes.
scan64# :: Word -> Parser r e ()
scan64# :: Word -> Parser r e ()
scan64# (W# Word#
c) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Addr# -> Int# -> Word#
indexWord64OffAddr# Addr#
s Int#
0# of
    Word#
c' -> case Word# -> Word# -> Int#
eqWord# Word#
c Word#
c' of
      Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
8#) Int#
n
      Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline scan64# #-}

-- | Unsafely read and return a byte from the input. It's not checked that the input is non-empty.
scanAny8# :: Parser r e Word8
scanAny8# :: Parser r e Word8
scanAny8# = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e Word8)
-> Parser r e Word8
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n -> Word8 -> Addr# -> Int# -> Res# e Word8
forall a e. a -> Addr# -> Int# -> Res# e a
OK# (Word# -> Word8
W8# (Addr# -> Int# -> Word#
indexWord8OffAddr# Addr#
s Int#
0#)) (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
1#) Int#
n
{-# inline scanAny8# #-}

scanPartial64# :: Int -> Word -> Parser r e ()
scanPartial64# :: Int -> Word -> Parser r e ()
scanPartial64# (I# Int#
len) (W# Word#
w) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  case Addr# -> Int# -> Word#
indexWordOffAddr# Addr#
s Int#
0# of
    Word#
w' -> case Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
8# Int# -> Int# -> Int#
-# Int#
len) Int#
3# of
      Int#
sh -> case Word# -> Int# -> Word#
uncheckedShiftL# Word#
w' Int#
sh of
        Word#
w' -> case Word# -> Int# -> Word#
uncheckedShiftRL# Word#
w' Int#
sh of
          Word#
w' -> case Word# -> Word# -> Int#
eqWord# Word#
w Word#
w' of
            Int#
1# -> () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
s Int#
len) Int#
n
            Int#
_  -> Res# e ()
forall e a. Res# e a
Fail#
{-# inline scanPartial64# #-}

-- | Decrease the current input position by the given number of bytes.
setBack# :: Int -> Parser r e ()
setBack# :: Int -> Parser r e ()
setBack# (I# Int#
i) = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e ())
-> Parser r e ()
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
s Int#
n ->
  () -> Addr# -> Int# -> Res# e ()
forall a e. a -> Addr# -> Int# -> Res# e a
OK# () (Addr# -> Int# -> Addr#
plusAddr# Addr#
s (Int# -> Int#
negateInt# Int#
i)) Int#
n
{-# inline setBack# #-}

-- | Template function, creates a @Parser r e ()@ which unsafely scans a given
--   sequence of bytes.
scanBytes# :: [Word] -> Q Exp
scanBytes# :: [Word] -> Q Exp
scanBytes# [Word]
bytes = do
  let !([Word]
leading, [Word]
w8s) = [Word] -> ([Word], [Word])
splitBytes [Word]
bytes
      !scanw8s :: Q Exp
scanw8s        = [Word] -> Q Exp
forall t. Lift t => [t] -> Q Exp
go [Word]
w8s where
                         go :: [t] -> Q Exp
go (t
w8:[] ) = [| scan64# w8 |]
                         go (t
w8:[t]
w8s) = [| scan64# w8 >> $(go w8s) |]
                         go []       = [| pure () |]
  case [Word]
w8s of
    [] -> [Word] -> Q Exp
go [Word]
leading
          where
            go :: [Word] -> Q Exp
go (Word
a:Word
b:Word
c:Word
d:[]) = let !w :: Word
w = [Word] -> Word
packBytes [Word
a, Word
b, Word
c, Word
d] in [| scan32# w |]
            go (Word
a:Word
b:Word
c:Word
d:[Word]
ws) = let !w :: Word
w = [Word] -> Word
packBytes [Word
a, Word
b, Word
c, Word
d] in [| scan32# w >> $(go ws) |]
            go (Word
a:Word
b:[])     = let !w :: Word
w = [Word] -> Word
packBytes [Word
a, Word
b]       in [| scan16# w |]
            go (Word
a:Word
b:[Word]
ws)     = let !w :: Word
w = [Word] -> Word
packBytes [Word
a, Word
b]       in [| scan16# w >> $(go ws) |]
            go (Word
a:[])       = [| scan8# a |]
            go []           = [| pure () |]
    [Word]
_  -> case [Word]
leading of

      []              -> Q Exp
scanw8s
      [Word
a]             -> [| scan8# a >> $scanw8s |]
      ws :: [Word]
ws@[Word
a, Word
b]       -> let !w :: Word
w = [Word] -> Word
packBytes [Word]
ws in [| scan16# w >> $scanw8s |]
      ws :: [Word]
ws@[Word
a, Word
b, Word
c, Word
d] -> let !w :: Word
w = [Word] -> Word
packBytes [Word]
ws in [| scan32# w >> $scanw8s |]
      [Word]
ws              -> let !w :: Word
w = [Word] -> Word
packBytes [Word]
ws
                             !l :: Int
l = [Word] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Word]
ws
                         in [| scanPartial64# l w >> $scanw8s |]


-- Switching code generation
--------------------------------------------------------------------------------

#if MIN_VERSION_base(4,15,0)
mkDoE = DoE Nothing
{-# inline mkDoE #-}
#else
mkDoE :: [Stmt] -> Exp
mkDoE = [Stmt] -> Exp
DoE
{-# inline mkDoE #-}
#endif

genTrie :: (Map (Maybe Int) Exp, Trie' (Rule, Int, Maybe Int)) -> Q Exp
genTrie :: (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int)) -> Q Exp
genTrie (Map (Maybe Int) Exp
rules, Trie' (Maybe Int, Int, Maybe Int)
t) = do
  Map (Maybe Int) (Name, Exp)
branches <- (Exp -> Q (Name, Exp))
-> Map (Maybe Int) Exp -> Q (Map (Maybe Int) (Name, Exp))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\Exp
e -> (,) (Name -> Exp -> (Name, Exp)) -> Q Name -> Q (Exp -> (Name, Exp))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> Q Name
newName String
"rule") Q (Exp -> (Name, Exp)) -> Q Exp -> Q (Name, Exp)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Exp -> Q Exp
forall (f :: * -> *) a. Applicative f => a -> f a
pure Exp
e) Map (Maybe Int) Exp
rules

  let ix :: Map a p -> a -> p
ix Map a p
m a
k = case a -> Map a p -> Maybe p
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup a
k Map a p
m of
        Maybe p
Nothing -> String -> p
forall a. HasCallStack => String -> a
error (String
"key not in map: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
k)
        Just p
a  -> p
a

  let ensure :: Maybe Int -> Maybe (Q Exp)
      ensure :: Maybe Int -> Maybe (Q Exp)
ensure = (Int -> Q Exp) -> Maybe Int -> Maybe (Q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Int
n -> [| ensureBytes# n |])

      fallback :: Rule -> Int ->  Q Exp
      fallback :: Maybe Int -> Int -> Q Exp
fallback Maybe Int
rule Int
0 = Exp -> Q Exp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Exp -> Q Exp) -> Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Name -> Exp
VarE (Name -> Exp) -> Name -> Exp
forall a b. (a -> b) -> a -> b
$ (Name, Exp) -> Name
forall a b. (a, b) -> a
fst ((Name, Exp) -> Name) -> (Name, Exp) -> Name
forall a b. (a -> b) -> a -> b
$ Map (Maybe Int) (Name, Exp) -> Maybe Int -> (Name, Exp)
forall a p. (Ord a, Show a) => Map a p -> a -> p
ix Map (Maybe Int) (Name, Exp)
branches Maybe Int
rule
      fallback Maybe Int
rule Int
n = [| setBack# n >> $(pure $ VarE $ fst $ ix branches rule) |]

  let go :: Trie' (Rule, Int, Maybe Int) -> Q Exp
      go :: Trie' (Maybe Int, Int, Maybe Int) -> Q Exp
go = \case
        Branch' (Maybe Int
r, Int
n, Maybe Int
alloc) Map Word (Trie' (Maybe Int, Int, Maybe Int))
ts
          | Map Word (Trie' (Maybe Int, Int, Maybe Int)) -> Bool
forall k a. Map k a -> Bool
M.null Map Word (Trie' (Maybe Int, Int, Maybe Int))
ts -> Exp -> Q Exp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Exp -> Q Exp) -> Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Name -> Exp
VarE (Name -> Exp) -> Name -> Exp
forall a b. (a -> b) -> a -> b
$ (Name, Exp) -> Name
forall a b. (a, b) -> a
fst ((Name, Exp) -> Name) -> (Name, Exp) -> Name
forall a b. (a -> b) -> a -> b
$ Map (Maybe Int) (Name, Exp)
branches Map (Maybe Int) (Name, Exp) -> Maybe Int -> (Name, Exp)
forall k a. Ord k => Map k a -> k -> a
M.! Maybe Int
r
          | Bool
otherwise -> do
              ![(Word, Exp)]
next         <- (((Word, Trie' (Maybe Int, Int, Maybe Int)) -> Q (Word, Exp))
-> [(Word, Trie' (Maybe Int, Int, Maybe Int))] -> Q [(Word, Exp)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (((Word, Trie' (Maybe Int, Int, Maybe Int)) -> Q (Word, Exp))
 -> [(Word, Trie' (Maybe Int, Int, Maybe Int))] -> Q [(Word, Exp)])
-> ((Trie' (Maybe Int, Int, Maybe Int) -> Q Exp)
    -> (Word, Trie' (Maybe Int, Int, Maybe Int)) -> Q (Word, Exp))
-> (Trie' (Maybe Int, Int, Maybe Int) -> Q Exp)
-> [(Word, Trie' (Maybe Int, Int, Maybe Int))]
-> Q [(Word, Exp)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Trie' (Maybe Int, Int, Maybe Int) -> Q Exp)
-> (Word, Trie' (Maybe Int, Int, Maybe Int)) -> Q (Word, Exp)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse) Trie' (Maybe Int, Int, Maybe Int) -> Q Exp
go (Map Word (Trie' (Maybe Int, Int, Maybe Int))
-> [(Word, Trie' (Maybe Int, Int, Maybe Int))]
forall k a. Map k a -> [(k, a)]
M.toList Map Word (Trie' (Maybe Int, Int, Maybe Int))
ts)
              !Exp
defaultCase  <- Maybe Int -> Int -> Q Exp
fallback Maybe Int
r (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

              let cases :: Exp
cases = [Stmt] -> Exp
mkDoE ([Stmt] -> Exp) -> [Stmt] -> Exp
forall a b. (a -> b) -> a -> b
$
                    [Pat -> Exp -> Stmt
BindS (Name -> Pat
VarP (String -> Name
mkName String
"c")) (Name -> Exp
VarE 'scanAny8#),
                      Exp -> Stmt
NoBindS (Exp -> [Match] -> Exp
CaseE (Name -> Exp
VarE (String -> Name
mkName String
"c"))
                         (((Word, Exp) -> Match) -> [(Word, Exp)] -> [Match]
forall a b. (a -> b) -> [a] -> [b]
map (\(Word
w, Exp
t) ->
                                 Pat -> Body -> [Dec] -> Match
Match (Lit -> Pat
LitP (Integer -> Lit
IntegerL (Word -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
w)))
                                       (Exp -> Body
NormalB Exp
t)
                                       [])
                              [(Word, Exp)]
next
                          [Match] -> [Match] -> [Match]
forall a. [a] -> [a] -> [a]
++ [Pat -> Body -> [Dec] -> Match
Match Pat
WildP (Exp -> Body
NormalB Exp
defaultCase) []]))]

              case Maybe Int -> Maybe (Q Exp)
ensure Maybe Int
alloc of
                Maybe (Q Exp)
Nothing    -> Exp -> Q Exp
forall (f :: * -> *) a. Applicative f => a -> f a
pure Exp
cases
                Just Q Exp
alloc -> [| branch $alloc $(pure cases) $(fallback r n) |]

        Path (Maybe Int
r, Int
n, Maybe Int
alloc) [Word]
ws Trie' (Maybe Int, Int, Maybe Int)
t ->
          case Maybe Int -> Maybe (Q Exp)
ensure Maybe Int
alloc of
            Maybe (Q Exp)
Nothing    -> [| branch $(scanBytes# ws) $(go t) $(fallback r n)|]
            Just Q Exp
alloc -> [| branch ($alloc >> $(scanBytes# ws)) $(go t) $(fallback r n) |]

  [DecQ] -> Q Exp -> Q Exp
letE
    (((Name, Exp) -> DecQ) -> [(Name, Exp)] -> [DecQ]
forall a b. (a -> b) -> [a] -> [b]
map (\(Name
x, Exp
rhs) -> PatQ -> BodyQ -> [DecQ] -> DecQ
valD (Name -> PatQ
varP Name
x) (Q Exp -> BodyQ
normalB (Exp -> Q Exp
forall (f :: * -> *) a. Applicative f => a -> f a
pure Exp
rhs)) []) (Map (Maybe Int) (Name, Exp) -> [(Name, Exp)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList Map (Maybe Int) (Name, Exp)
branches))
    (Trie' (Maybe Int, Int, Maybe Int) -> Q Exp
go Trie' (Maybe Int, Int, Maybe Int)
t)

parseSwitch :: Q Exp -> Q ([(String, Exp)], Maybe Exp)
parseSwitch :: Q Exp -> Q ([(String, Exp)], Maybe Exp)
parseSwitch Q Exp
exp = Q Exp
exp Q Exp
-> (Exp -> Q ([(String, Exp)], Maybe Exp))
-> Q ([(String, Exp)], Maybe Exp)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  CaseE (UnboundVarE Name
_) []    -> String -> Q ([(String, Exp)], Maybe Exp)
forall a. HasCallStack => String -> a
error String
"switch: empty clause list"
  CaseE (UnboundVarE Name
_) [Match]
cases -> do
    (![Match]
cases, !Match
last) <- ([Match], Match) -> Q ([Match], Match)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Match] -> [Match]
forall a. [a] -> [a]
init [Match]
cases, [Match] -> Match
forall a. [a] -> a
last [Match]
cases)
    ![(String, Exp)]
cases <- [Match] -> (Match -> Q (String, Exp)) -> Q [(String, Exp)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Match]
cases \case
      Match (LitP (StringL String
str)) (NormalB Exp
rhs) [] -> (String, Exp) -> Q (String, Exp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String
str, Exp
rhs)
      Match
_ -> String -> Q (String, Exp)
forall a. HasCallStack => String -> a
error String
"switch: expected a match clause on a string literal"
    (![(String, Exp)]
cases, !Maybe Exp
last) <- case Match
last of
      Match (LitP (StringL String
str)) (NormalB Exp
rhs) [] -> ([(String, Exp)], Maybe Exp) -> Q ([(String, Exp)], Maybe Exp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(String, Exp)]
cases [(String, Exp)] -> [(String, Exp)] -> [(String, Exp)]
forall a. [a] -> [a] -> [a]
++ [(String
str, Exp
rhs)], Maybe Exp
forall k1. Maybe k1
Nothing)
      Match Pat
WildP                (NormalB Exp
rhs) [] -> ([(String, Exp)], Maybe Exp) -> Q ([(String, Exp)], Maybe Exp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(String, Exp)]
cases, Exp -> Maybe Exp
forall k1. k1 -> Maybe k1
Just Exp
rhs)
      Match
_ -> String -> Q ([(String, Exp)], Maybe Exp)
forall a. HasCallStack => String -> a
error String
"switch: expected a match clause on a string literal or a wildcard"
    ([(String, Exp)], Maybe Exp) -> Q ([(String, Exp)], Maybe Exp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(String, Exp)]
cases, Maybe Exp
last)
  Exp
_ -> String -> Q ([(String, Exp)], Maybe Exp)
forall a. HasCallStack => String -> a
error String
"switch: expected a \"case _ of\" expression"

genSwitchTrie' :: Maybe Exp -> [(String, Exp)] -> Maybe Exp
              -> (Map (Maybe Int) Exp, Trie' (Rule, Int, Maybe Int))
genSwitchTrie' :: Maybe Exp
-> [(String, Exp)]
-> Maybe Exp
-> (Map (Maybe Int) Exp, Trie' (Maybe Int, Int, Maybe Int))
genSwitchTrie' Maybe Exp
postAction [(String, Exp)]
cases Maybe Exp
fallback =

  let (![(Maybe Int, Exp)]
branches, ![(Int, String)]
strings) = [((Maybe Int, Exp), (Int, String))]
-> ([(Maybe Int, Exp)], [(Int, String)])
forall a b. [(a, b)] -> ([a], [b])
unzip do
        (!Int
i, (!String
str, !Exp
rhs)) <- [Int] -> [(String, Exp)] -> [(Int, (String, Exp))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [(String, Exp)]
cases
        case Maybe Exp
postAction of
          Maybe Exp
Nothing    -> ((Maybe Int, Exp), (Int, String))
-> [((Maybe Int, Exp), (Int, String))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Int -> Maybe Int
forall k1. k1 -> Maybe k1
Just Int
i, Exp
rhs), (Int
i, String
str))
          Just !Exp
post -> ((Maybe Int, Exp), (Int, String))
-> [((Maybe Int, Exp), (Int, String))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Int -> Maybe Int
forall k1. k1 -> Maybe k1
Just Int
i, (Name -> Exp
VarE '(>>)) Exp -> Exp -> Exp
`AppE` Exp
post Exp -> Exp -> Exp
`AppE` Exp
rhs), (Int
i, String
str))

      !m :: Map (Maybe Int) Exp
m    =  [(Maybe Int, Exp)] -> Map (Maybe Int) Exp
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ((Maybe Int
forall k1. Maybe k1
Nothing, Exp -> (Exp -> Exp) -> Maybe Exp -> Exp
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Name -> Exp
VarE 'empty) Exp -> Exp
forall a. a -> a
id Maybe Exp
fallback) (Maybe Int, Exp) -> [(Maybe Int, Exp)] -> [(Maybe Int, Exp)]
forall k1. k1 -> [k1] -> [k1]
: [(Maybe Int, Exp)]
branches)
      !trie :: Trie' (Maybe Int, Int, Maybe Int)
trie = [(Int, String)] -> Trie' (Maybe Int, Int, Maybe Int)
compileTrie [(Int, String)]
strings
  in (Map (Maybe Int) Exp
m , Trie' (Maybe Int, Int, Maybe Int)
trie)

--------------------------------------------------------------------------------

withAnyWord8# :: (Word8'# -> Parser r e a) -> Parser r e a
withAnyWord8# :: (Word# -> Parser r e a) -> Parser r e a
withAnyWord8# Word# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
buf of
  Int#
1# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Word#
indexWord8OffAddr# Addr#
buf Int#
0# of
    Word#
w# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Word# -> Parser r e a
p Word#
w#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) Int#
n
{-# inline withAnyWord8# #-}

withAnyWord16# :: (Word16'# -> Parser r e a) -> Parser r e a
withAnyWord16# :: (Word# -> Parser r e a) -> Parser r e a
withAnyWord16# Word# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Int#
2# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
buf of
  Int#
0# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Word#
indexWord16OffAddr# Addr#
buf Int#
0# of
    Word#
w# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Word# -> Parser r e a
p Word#
w#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#) Int#
n
{-# inline withAnyWord16# #-}

withAnyWord32# :: (Word32'# -> Parser r e a) -> Parser r e a
withAnyWord32# :: (Word# -> Parser r e a) -> Parser r e a
withAnyWord32# Word# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Int#
4# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
buf of
  Int#
0# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Word#
indexWord32OffAddr# Addr#
buf Int#
0# of
    Word#
w# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Word# -> Parser r e a
p Word#
w#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
4#) Int#
n
{-# inline withAnyWord32# #-}

withAnyWord64# :: (Word# -> Parser r e a) -> Parser r e a
withAnyWord64# :: (Word# -> Parser r e a) -> Parser r e a
withAnyWord64# Word# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Int#
8# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
buf of
  Int#
0# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Word#
indexWordOffAddr# Addr#
buf Int#
0# of
    Word#
w# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Word# -> Parser r e a
p Word#
w#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
8#) Int#
n
{-# inline withAnyWord64# #-}

withAnyInt8# :: (Int8'# -> Parser r e a) -> Parser r e a
withAnyInt8# :: (Int# -> Parser r e a) -> Parser r e a
withAnyInt8# Int# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Addr# -> Addr# -> Int#
eqAddr# Addr#
eob Addr#
buf of
  Int#
1# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Int#
indexInt8OffAddr# Addr#
buf Int#
0# of
    Int#
i# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Int# -> Parser r e a
p Int#
i#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
1#) Int#
n
{-# inline withAnyInt8# #-}

withAnyInt16# :: (Int16'# -> Parser r e a) -> Parser r e a
withAnyInt16# :: (Int# -> Parser r e a) -> Parser r e a
withAnyInt16# Int# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Int#
2# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
buf of
  Int#
0# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Int#
indexInt16OffAddr# Addr#
buf Int#
0# of
    Int#
i# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Int# -> Parser r e a
p Int#
i#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
2#) Int#
n
{-# inline withAnyInt16# #-}

withAnyInt32# :: (Int32'# -> Parser r e a) -> Parser r e a
withAnyInt32# :: (Int# -> Parser r e a) -> Parser r e a
withAnyInt32# Int# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Int#
4# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
buf of
  Int#
0# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Int#
indexInt32OffAddr# Addr#
buf Int#
0# of
    Int#
i# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Int# -> Parser r e a
p Int#
i#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
4#) Int#
n
{-# inline withAnyInt32# #-}

withAnyInt64# :: (Int# -> Parser r e a) -> Parser r e a
withAnyInt64# :: (Int# -> Parser r e a) -> Parser r e a
withAnyInt64# Int# -> Parser r e a
p = (ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
forall r e a.
(ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a)
-> Parser r e a
Parser \ForeignPtrContents
fp !r
r Addr#
eob Addr#
buf Int#
n -> case Int#
8# Int# -> Int# -> Int#
<=# Addr# -> Addr# -> Int#
minusAddr# Addr#
eob Addr#
buf of
  Int#
0# -> Res# e a
forall e a. Res# e a
Fail#
  Int#
_  -> case Addr# -> Int# -> Int#
indexInt64OffAddr# Addr#
buf Int#
0# of
    Int#
i# -> Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
forall r e a.
Parser r e a
-> ForeignPtrContents -> r -> Addr# -> Addr# -> Int# -> Res# e a
runParser# (Int# -> Parser r e a
p Int#
i#) ForeignPtrContents
fp r
r Addr#
eob (Addr# -> Int# -> Addr#
plusAddr# Addr#
buf Int#
8#) Int#
n
{-# inline withAnyInt64# #-}

--------------------------------------------------------------------------------

-- | Parse any 'Word8' (byte).
anyWord8 :: Parser r e Word8
anyWord8 :: Parser r e Word8
anyWord8 = (Word# -> Parser r e Word8) -> Parser r e Word8
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord8# (\Word#
w# -> Word8 -> Parser r e Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word8
W8# Word#
w#))
{-# inline anyWord8 #-}

-- | Skip any 'Word8' (byte).
anyWord8_ :: Parser r e ()
anyWord8_ :: Parser r e ()
anyWord8_ = () () -> Parser r e Word8 -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e Word8
forall r e. Parser r e Word8
anyWord8
{-# inline anyWord8_ #-}

-- | Parse any 'Word16'.
anyWord16 :: Parser r e Word16
anyWord16 :: Parser r e Word16
anyWord16 = (Word# -> Parser r e Word16) -> Parser r e Word16
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord16# (\Word#
w# -> Word16 -> Parser r e Word16
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word16
W16# Word#
w#))
{-# inline anyWord16 #-}

-- | Skip any 'Word16'.
anyWord16_ :: Parser r e ()
anyWord16_ :: Parser r e ()
anyWord16_ = () () -> Parser r e Word16 -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e Word16
forall r e. Parser r e Word16
anyWord16
{-# inline anyWord16_ #-}

-- | Parse any 'Word32'.
anyWord32 :: Parser r e Word32
anyWord32 :: Parser r e Word32
anyWord32 = (Word# -> Parser r e Word32) -> Parser r e Word32
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord32# (\Word#
w# -> Word32 -> Parser r e Word32
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word32
W32# Word#
w#))
{-# inline anyWord32 #-}

-- | Skip any 'Word32'.
anyWord32_ :: Parser r e ()
anyWord32_ :: Parser r e ()
anyWord32_ = () () -> Parser r e Word32 -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e Word32
forall r e. Parser r e Word32
anyWord32
{-# inline anyWord32_ #-}

-- | Parse any 'Word64'.
anyWord64 :: Parser r e Word64
anyWord64 :: Parser r e Word64
anyWord64 = (Word# -> Parser r e Word64) -> Parser r e Word64
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord64# (\Word#
w# -> Word64 -> Parser r e Word64
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word64
W64# Word#
w#))
{-# inline anyWord64 #-}

-- | Skip any 'Word64'.
anyWord64_ :: Parser r e ()
anyWord64_ :: Parser r e ()
anyWord64_ = () () -> Parser r e Word64 -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e Word64
forall r e. Parser r e Word64
anyWord64
{-# inline anyWord64_ #-}

-- | Parse any 'Word'.
anyWord :: Parser r e Word
anyWord :: Parser r e Word
anyWord = (Word# -> Parser r e Word) -> Parser r e Word
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord64# (\Word#
w# -> Word -> Parser r e Word
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word
W# Word#
w#))
{-# inline anyWord #-}

-- | Skip any 'Word'.
anyWord_ :: Parser r e ()
anyWord_ :: Parser r e ()
anyWord_ = () () -> Parser r e Word -> Parser r e ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser r e Word
forall r e. Parser r e Word
anyWord
{-# inline anyWord_ #-}

--------------------------------------------------------------------------------

-- | Parse any 'Int8'.
anyInt8 :: Parser r e Int8
anyInt8 :: Parser r e Int8
anyInt8 = (Int# -> Parser r e Int8) -> Parser r e Int8
forall r e a. (Int# -> Parser r e a) -> Parser r e a
withAnyInt8# (\Int#
i# -> Int8 -> Parser r e Int8
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int8
I8# Int#
i#))
{-# inline anyInt8 #-}

-- | Parse any 'Int16'.
anyInt16 :: Parser r e Int16
anyInt16 :: Parser r e Int16
anyInt16 = (Int# -> Parser r e Int16) -> Parser r e Int16
forall r e a. (Int# -> Parser r e a) -> Parser r e a
withAnyInt16# (\Int#
i# -> Int16 -> Parser r e Int16
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int16
I16# Int#
i#))
{-# inline anyInt16 #-}

-- | Parse any 'Int32'.
anyInt32 :: Parser r e Int32
anyInt32 :: Parser r e Int32
anyInt32 = (Int# -> Parser r e Int32) -> Parser r e Int32
forall r e a. (Int# -> Parser r e a) -> Parser r e a
withAnyInt32# (\Int#
i# -> Int32 -> Parser r e Int32
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int32
I32# Int#
i#))
{-# inline anyInt32 #-}

-- | Parse any 'Int64'.
anyInt64 :: Parser r e Int64
anyInt64 :: Parser r e Int64
anyInt64 = (Int# -> Parser r e Int64) -> Parser r e Int64
forall r e a. (Int# -> Parser r e a) -> Parser r e a
withAnyInt64# (\Int#
i# -> Int64 -> Parser r e Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int64
I64# Int#
i#))
{-# inline anyInt64 #-}

-- | Parse any 'Int'.
anyInt :: Parser r e Int
anyInt :: Parser r e Int
anyInt = (Int# -> Parser r e Int) -> Parser r e Int
forall r e a. (Int# -> Parser r e a) -> Parser r e a
withAnyInt64# (\Int#
i# -> Int -> Parser r e Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int
I# Int#
i#))
{-# inline anyInt #-}

--------------------------------------------------------------------------------

-- | Parse any 'Word16' (little-endian).
anyWord16le :: Parser r e Word16
anyWord16le :: Parser r e Word16
anyWord16le = Parser r e Word16
forall r e. Parser r e Word16
anyWord16
{-# inline anyWord16le #-}

-- | Parse any 'Word16' (big-endian).
anyWord16be :: Parser r e Word16
anyWord16be :: Parser r e Word16
anyWord16be = (Word# -> Parser r e Word16) -> Parser r e Word16
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord16# (\Word#
w# -> Word16 -> Parser r e Word16
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word16
W16# (Word# -> Word#
byteSwap16'# Word#
w#)))
{-# inline anyWord16be #-}

-- | Parse any 'Word32' (little-endian).
anyWord32le :: Parser r e Word32
anyWord32le :: Parser r e Word32
anyWord32le = Parser r e Word32
forall r e. Parser r e Word32
anyWord32
{-# inline anyWord32le #-}

-- | Parse any 'Word32' (big-endian).
anyWord32be :: Parser r e Word32
anyWord32be :: Parser r e Word32
anyWord32be = (Word# -> Parser r e Word32) -> Parser r e Word32
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord32# (\Word#
w# -> Word32 -> Parser r e Word32
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word32
W32# (Word# -> Word#
byteSwap32'# Word#
w#)))
{-# inline anyWord32be #-}

-- | Parse any 'Word64' (little-endian).
anyWord64le :: Parser r e Word64
anyWord64le :: Parser r e Word64
anyWord64le = Parser r e Word64
forall r e. Parser r e Word64
anyWord64
{-# inline anyWord64le #-}

-- | Parse any 'Word64' (big-endian).
anyWord64be :: Parser r e Word64
anyWord64be :: Parser r e Word64
anyWord64be = (Word# -> Parser r e Word64) -> Parser r e Word64
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord64# (\Word#
w# -> Word64 -> Parser r e Word64
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word# -> Word64
W64# (Word# -> Word#
byteSwap# Word#
w#)))
{-# inline anyWord64be #-}

--------------------------------------------------------------------------------

-- | Parse any 'Int16' (little-endian).
anyInt16le :: Parser r e Int16
anyInt16le :: Parser r e Int16
anyInt16le = Parser r e Int16
forall r e. Parser r e Int16
anyInt16
{-# inline anyInt16le #-}

-- | Parse any 'Int16' (big-endian).
anyInt16be :: Parser r e Int16
anyInt16be :: Parser r e Int16
anyInt16be = (Word# -> Parser r e Int16) -> Parser r e Int16
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord16# (\Word#
w# -> Int16 -> Parser r e Int16
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int16
I16# (Word# -> Int#
word16ToInt16# (Word# -> Word#
byteSwap16'# Word#
w#))))
{-# inline anyInt16be #-}

-- | Parse any 'Int32' (little-endian).
anyInt32le :: Parser r e Int32
anyInt32le :: Parser r e Int32
anyInt32le = Parser r e Int32
forall r e. Parser r e Int32
anyInt32
{-# inline anyInt32le #-}

-- | Parse any 'Int32' (big-endian).
anyInt32be :: Parser r e Int32
anyInt32be :: Parser r e Int32
anyInt32be = (Word# -> Parser r e Int32) -> Parser r e Int32
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord32# (\Word#
w# -> Int32 -> Parser r e Int32
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int32
I32# (Word# -> Int#
word32ToInt32# (Word# -> Word#
byteSwap32'# Word#
w#))))
{-# inline anyInt32be #-}

-- | Parse any 'Int64' (little-endian).
anyInt64le :: Parser r e Int64
anyInt64le :: Parser r e Int64
anyInt64le = Parser r e Int64
forall r e. Parser r e Int64
anyInt64
{-# inline anyInt64le #-}

-- | Parse any 'Int64' (big-endian).
anyInt64be :: Parser r e Int64
anyInt64be :: Parser r e Int64
anyInt64be = (Word# -> Parser r e Int64) -> Parser r e Int64
forall r e a. (Word# -> Parser r e a) -> Parser r e a
withAnyWord64# (\Word#
w# -> Int64 -> Parser r e Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int# -> Int64
I64# (Word# -> Int#
word2Int# (Word# -> Word#
byteSwap# Word#
w#))))
{-# inline anyInt64be #-}