{-# LANGUAGE BangPatterns
           , UnboxedTuples #-}

{- | Functions for parsing bounded integers expressed as numbers
     with no fractional part or exponent.

     Parsing functions in this module are only guaranteed to operate correctly when
     their arguments are sensible and the input number has no leading zeroes.

     == Example

     Converting @"-123,040,567 "@ to an 'Int32', skipping operations
     outside of this module:

 @
 >>> 'parse' ('wholeInt32Dec' () Minus (WholeInt 0) 0) "123,040,567 "
 (Scrap 3 ",040,567 " End,Right (WholeInt 123,3))

 >>> parse (wholeInt32Dec () Minus (WholeInt 123) 3) "040,567 "
 (Scrap 3 ",567 " End,Right (WholeInt 123040,6))

 >>> parse (wholeInt32Dec () Minus (WholeInt 123040) 6) "567 "
 (Scrap 3 " " End,Right (WholeInt 123040567,9))

 >>> 'wholeToInt32' Minus (WholeInt 123040567)
 -123040567
 @
 -}

module Parser.Lathe.Numeric.Integral
  ( -- * Representation
    -- ** Signed
    Sign (..)
  , WholeInt (..)

    -- | === Conversions
  , wholeToInt8
  , wholeToInt16
  , wholeToInt32
  , wholeToInt64
  , wholeToInt

    -- * Parsing
    -- ** Decimal
    -- *** Unsigned
  , wholeWord8Dec
  , wholeWord16Dec
  , wholeWord32Dec
  , wholeWord64Dec
  , wholeWordDec
  , wholeNaturalDec

    -- *** Signed
  , wholeInt8Dec
  , wholeInt16Dec
  , wholeInt32Dec
  , wholeInt64Dec
  , wholeIntDec

    -- ** Hexadecimal
    -- *** Unsigned
  , wholeWord8Hex
  , wholeWord16Hex
  , wholeWord32Hex
  , wholeWord64Hex
  , wholeWordHex
  ) where

import           Parser.Lathe.Radix
import           Parser.Lathe.Internal
import           Parser.Lathe.Internal.Bitness
import           Parser.Lathe.Numeric.Integral.Internal
import           Parser.Lathe.Numeric.Internal

import           Data.Bits
import qualified Data.ByteString as B (ByteString)
import qualified Data.ByteString.Unsafe as B
import           Data.Int
import           Data.Word
import           Numeric.Natural



-- | Consume up to 3 decimal digits into a 'Word8'.
wholeWord8Dec
  :: overflow
  -> Word8
  -> Int      -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (Word8, Int)
wholeWord8Dec :: forall overflow.
overflow -> Word8 -> Int -> Parser overflow (Word8, Int)
wholeWord8Dec = (Int, Word8, Word8)
-> overflow -> Word8 -> Int -> Parser overflow (Word8, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a) -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ (Int, Word8, Word8)
forall a. Num a => (Int, a, a)
u8

-- | Consume up to 5 decimal digits into a 'Word16'.
wholeWord16Dec
  :: overflow
  -> Word16
  -> Int      -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (Word16, Int)
wholeWord16Dec :: forall overflow.
overflow -> Word16 -> Int -> Parser overflow (Word16, Int)
wholeWord16Dec = (Int, Word16, Word16)
-> overflow -> Word16 -> Int -> Parser overflow (Word16, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a) -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ (Int, Word16, Word16)
forall a. Num a => (Int, a, a)
u16

-- | Consume up to 10 decimal digits into a 'Word32'.
wholeWord32Dec
  :: overflow
  -> Word32
  -> Int      -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (Word32, Int)
wholeWord32Dec :: forall overflow.
overflow -> Word32 -> Int -> Parser overflow (Word32, Int)
wholeWord32Dec = (Int, Word32, Word32)
-> overflow -> Word32 -> Int -> Parser overflow (Word32, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a) -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ (Int, Word32, Word32)
forall a. Num a => (Int, a, a)
u32

-- | Consume up to 20 decimal digits into a 'Word64'.
wholeWord64Dec
  :: overflow
  -> Word64
  -> Int      -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (Word64, Int)
wholeWord64Dec :: forall overflow.
overflow -> Word64 -> Int -> Parser overflow (Word64, Int)
wholeWord64Dec = (Int, Word64, Word64)
-> overflow -> Word64 -> Int -> Parser overflow (Word64, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a) -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ (Int, Word64, Word64)
forall a. Num a => (Int, a, a)
u64

-- | Consume up to 10 or 20 decimal digits
--   (depending on machine integer size) into a 'Word'.
wholeWordDec
  :: overflow
  -> Word
  -> Int      -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (Word, Int)
wholeWordDec :: forall overflow.
overflow -> Word -> Int -> Parser overflow (Word, Int)
wholeWordDec = (Int, Word, Word)
-> overflow -> Word -> Int -> Parser overflow (Word, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a) -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ ((Int, Word, Word) -> (Int, Word, Word) -> (Int, Word, Word)
forall a. a -> a -> a
caseWordSize_32_64 (Int, Word, Word)
forall a. Num a => (Int, a, a)
u32 (Int, Word, Word)
forall a. Num a => (Int, a, a)
u64)


data State a = State
                 {-# UNPACK #-} !(Flow a)
                 {-# UNPACK #-} !Int      -- ^ Number of bytes consumed

data Flow a = Number !a
            | Overflow

{-# INLINE wholeWordDec_ #-}
wholeWordDec_
  :: (Ord a, Num a)
  => (Int, a, a)
  -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ :: forall a overflow.
(Ord a, Num a) =>
(Int, a, a) -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordDec_ (Int
len, a
bound, a
tip) overflow
overflow = \a
v Int
n -> do
  State Flow a
r Int
n' <- a -> Int -> Parser (State a) (State a)
forall {b}. a -> Int -> Parser (State a) b
go a
v Int
n Parser (State a) (State a)
-> (State a -> Parser overflow (State a))
-> Parser overflow (State a)
forall e a x. Parser e a -> (e -> Parser x a) -> Parser x a
`catch` State a -> Parser overflow (State a)
forall a. a -> Parser overflow a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Int64 -> Parser overflow ()
forall never. Int64 -> Parser never ()
unsafeSkipEndOr (Int64 -> Parser overflow ()) -> Int64 -> Parser overflow ()
forall a b. (a -> b) -> a -> b
$ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
  case Flow a
r of
    Number a
v' -> (a, Int) -> Parser overflow (a, Int)
forall a. a -> Parser overflow a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
v', Int
n')
    Flow a
Overflow  -> overflow -> Parser overflow (a, Int)
forall e a. e -> Parser e a
err overflow
overflow
  where
    go :: a -> Int -> Parser (State a) b
go !a
v !Int
n = do
      Word8
w <- State a -> Parser (State a) Word8
forall end. end -> Parser end Word8
word8 (State a -> Parser (State a) Word8)
-> State a -> Parser (State a) Word8
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n
      case Word8 -> Maybe Word8
dec Word8
w of
        Maybe Word8
Nothing -> State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n
        Just Word8
i  -> let !v' :: a
v' = a
v a -> a -> a
forall a. Num a => a -> a -> a
* a
10 a -> a -> a
forall a. Num a => a -> a -> a
+ Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i
                       n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

                   in if Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
len
                        then a -> Int -> Parser (State a) b
go a
v' Int
n'
                        else case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
v a
bound of
                               Ordering
LT -> a -> Int -> Parser (State a) b
forall {a} {b}. a -> Int -> Parser (State a) b
checkOverflow a
v' Int
n'

                               Ordering
EQ -> if Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
tip
                                       then a -> Int -> Parser (State a) b
forall {a} {b}. a -> Int -> Parser (State a) b
checkOverflow a
v' Int
n'
                                       else State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
forall a. Flow a
Overflow Int
n

                               Ordering
GT -> State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
forall a. Flow a
Overflow Int
n

    checkOverflow :: a -> Int -> Parser (State a) b
checkOverflow !a
v !Int
n = do
      Word8
w <- State a -> Parser (State a) Word8
forall end. end -> Parser end Word8
word8 (State a -> Parser (State a) Word8)
-> State a -> Parser (State a) Word8
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n

      let !(# Flow a
r #) = case Word8 -> Maybe Word8
dec Word8
w of
                       Maybe Word8
Nothing -> (# a -> Flow a
forall a. a -> Flow a
Number a
v #)
                       Just Word8
_  -> (# Flow a
forall a. Flow a
Overflow #)
      State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
r Int
n



data Digit = Digit !Word !Int

data Delim = Chunk
           | Rest
             deriving Int -> Delim -> ShowS
[Delim] -> ShowS
Delim -> String
(Int -> Delim -> ShowS)
-> (Delim -> String) -> ([Delim] -> ShowS) -> Show Delim
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Delim -> ShowS
showsPrec :: Int -> Delim -> ShowS
$cshow :: Delim -> String
show :: Delim -> String
$cshowList :: [Delim] -> ShowS
showList :: [Delim] -> ShowS
Show

data Return = Return !Delim !Word !Int
              deriving Int -> Return -> ShowS
[Return] -> ShowS
Return -> String
(Int -> Return -> ShowS)
-> (Return -> String) -> ([Return] -> ShowS) -> Show Return
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Return -> ShowS
showsPrec :: Int -> Return -> ShowS
$cshow :: Return -> String
show :: Return -> String
$cshowList :: [Return] -> ShowS
showList :: [Return] -> ShowS
Show

data Semi = Edge
          | Part !Word !Int
            deriving Int -> Semi -> ShowS
[Semi] -> ShowS
Semi -> String
(Int -> Semi -> ShowS)
-> (Semi -> String) -> ([Semi] -> ShowS) -> Show Semi
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Semi -> ShowS
showsPrec :: Int -> Semi -> ShowS
$cshow :: Semi -> String
show :: Semi -> String
$cshowList :: [Semi] -> ShowS
showList :: [Semi] -> ShowS
Show

unsafeWordDec :: Parser never Return
unsafeWordDec :: forall never. Parser never Return
unsafeWordDec = do
  Digit Word
v Int
n <- Word -> Int -> Parser Digit Digit
forall {b}. Word -> Int -> Parser Digit b
go Word
0 Int
0 Parser Digit Digit
-> (Digit -> Parser never Digit) -> Parser never Digit
forall e a x. Parser e a -> (e -> Parser x a) -> Parser x a
`catch` Digit -> Parser never Digit
forall a. a -> Parser never a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Int64 -> Parser never ()
forall never. Int64 -> Parser never ()
unsafeSkipEndOr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)
  Return -> Parser never Return
forall a. a -> Parser never a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delim -> Word -> Int -> Return
Return Delim
Rest Word
v Int
n)
  where
    go :: Word -> Int -> Parser Digit b
go !Word
v !Int
n = do
      Word8
w <- Digit -> Parser Digit Word8
forall end. end -> Parser end Word8
word8 (Digit -> Parser Digit Word8) -> Digit -> Parser Digit Word8
forall a b. (a -> b) -> a -> b
$ Word -> Int -> Digit
Digit Word
v Int
n
      case Word8 -> Maybe Word8
dec Word8
w of
        Maybe Word8
Nothing -> Digit -> Parser Digit b
forall e a. e -> Parser e a
err (Digit -> Parser Digit b) -> Digit -> Parser Digit b
forall a b. (a -> b) -> a -> b
$ Word -> Int -> Digit
Digit Word
v Int
n
        Just Word8
i  -> let !v' :: Word
v' = Word
v Word -> Word -> Word
forall a. Num a => a -> a -> a
* Word
10 Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word8 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i
                       !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

                   in Word -> Int -> Parser Digit b
go Word
v' Int
n'

bulkDec :: Int -> B.ByteString -> (# Res Semi Return #)
bulkDec :: Int -> ByteString -> (# Res Semi Return #)
bulkDec Int
len = \ByteString
b ->
  
  let go :: Int -> Word -> (# Res Semi Return #)
go Int
n Word
v
        | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len  = (# Return -> Res Semi Return
forall a e. a -> Res e a
Yes (Delim -> Word -> Int -> Return
Return Delim
Chunk Word
v Int
len) #)
        | Bool
otherwise =
            case Word8 -> Maybe Word8
dec (Word8 -> Maybe Word8) -> Word8 -> Maybe Word8
forall a b. (a -> b) -> a -> b
$ ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
n of
              Maybe Word8
Nothing -> (# Semi -> Res Semi Return
forall e a. e -> Res e a
No (Word -> Int -> Semi
Part Word
v Int
n) #)
              Just Word8
i  -> Int -> Word -> (# Res Semi Return #)
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Word -> (# Res Semi Return #)) -> Word -> (# Res Semi Return #)
forall a b. (a -> b) -> a -> b
$ Word
v Word -> Word -> Word
forall a. Num a => a -> a -> a
* Word
10 Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word8 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i


  in Int -> Word -> (# Res Semi Return #)
go Int
0 Word
0

-- | Consume any number of decimal digits into a 'Natural'.
wholeNaturalDec :: Natural -> Parser never Natural
wholeNaturalDec :: forall never. Natural -> Parser never Natural
wholeNaturalDec Natural
v0 = Natural -> Parser never Natural
forall {b} {x}. Num b => b -> Parser x b
go Natural
v0
  where
    digitsOf10 :: Int
digitsOf10 = Int -> Int -> Int
forall a. a -> a -> a
caseWordSize_32_64 Int
9 Int
19

    go :: b -> Parser x b
go !b
vT = do
      Return Delim
delim Word
v Int
n <- Int
-> (ByteString -> (# Res Semi Return #))
-> Semi
-> Parser Semi Return
forall e a. Int -> (ByteString -> (# Res e a #)) -> e -> Parser e a
unsafeRead Int
digitsOf10 (Int -> ByteString -> (# Res Semi Return #)
bulkDec Int
digitsOf10) Semi
Edge
                            Parser Semi Return -> (Semi -> Parser x Return) -> Parser x Return
forall e a x. Parser e a -> (e -> Parser x a) -> Parser x a
`catch` \Semi
semi ->
                              case Semi
semi of
                                Semi
Edge     -> Parser x Return
forall never. Parser never Return
unsafeWordDec
                                Part Word
v Int
n -> do
                                  Int64 -> Parser x ()
forall never. Int64 -> Parser never ()
unsafeSkipEndOr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)
                                  Return -> Parser x Return
forall a. a -> Parser x a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Return -> Parser x Return) -> Return -> Parser x Return
forall a b. (a -> b) -> a -> b
$ Delim -> Word -> Int -> Return
Return Delim
Rest Word
v Int
n

      let !vT' :: b
vT' = b
vT b -> b -> b
forall a. Num a => a -> a -> a
* (b
10 b -> Int -> b
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
n) b -> b -> b
forall a. Num a => a -> a -> a
+ Word -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
v

      case Delim
delim of
        Delim
Chunk -> b -> Parser x b
go b
vT'
        Delim
Rest  -> b -> Parser x b
forall a. a -> Parser x a
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
vT'




-- | Consume up to 2 hexadecimal digits into a 'Word8'.
wholeWord8Hex
  :: overflow
  -> Word8
  -> Int      -- ^ Number of hexadecimal digits consumed by this number.
  -> Parser overflow (Word8, Int)
wholeWord8Hex :: forall overflow.
overflow -> Word8 -> Int -> Parser overflow (Word8, Int)
wholeWord8Hex = Int -> overflow -> Word8 -> Int -> Parser overflow (Word8, Int)
forall a overflow.
(Bits a, Num a) =>
Int -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ Int
2

-- | Consume up to 4 hexadecimal digits into a 'Word16'.
wholeWord16Hex
  :: overflow
  -> Word16
  -> Int      -- ^ Number of hexadecimal digits consumed by this number.
  -> Parser overflow (Word16, Int)
wholeWord16Hex :: forall overflow.
overflow -> Word16 -> Int -> Parser overflow (Word16, Int)
wholeWord16Hex = Int -> overflow -> Word16 -> Int -> Parser overflow (Word16, Int)
forall a overflow.
(Bits a, Num a) =>
Int -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ Int
4

-- | Consume up to 8 hexadecimal digits into a 'Word32'.
wholeWord32Hex
  :: overflow
  -> Word32
  -> Int      -- ^ Number of hexadecimal digits consumed by this number.
  -> Parser overflow (Word32, Int)
wholeWord32Hex :: forall overflow.
overflow -> Word32 -> Int -> Parser overflow (Word32, Int)
wholeWord32Hex = Int -> overflow -> Word32 -> Int -> Parser overflow (Word32, Int)
forall a overflow.
(Bits a, Num a) =>
Int -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ Int
8

-- | Consume up to 16 hexadecimal digits into a 'Word64'.
wholeWord64Hex
  :: overflow
  -> Word64
  -> Int      -- ^ Number of hexadecimal digits consumed by this number.
  -> Parser overflow (Word64, Int)
wholeWord64Hex :: forall overflow.
overflow -> Word64 -> Int -> Parser overflow (Word64, Int)
wholeWord64Hex = Int -> overflow -> Word64 -> Int -> Parser overflow (Word64, Int)
forall a overflow.
(Bits a, Num a) =>
Int -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ Int
16

-- | Consume up to 8 or 16 hexadecimal digits
--   (depending on current platform's integer size) into a 'Word'.
wholeWordHex
  :: overflow
  -> Word
  -> Int      -- ^ Number of hexadecimal digits consumed by this number.
  -> Parser overflow (Word, Int)
wholeWordHex :: forall overflow.
overflow -> Word -> Int -> Parser overflow (Word, Int)
wholeWordHex = Int -> overflow -> Word -> Int -> Parser overflow (Word, Int)
forall a overflow.
(Bits a, Num a) =>
Int -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ (Int -> Int -> Int
forall a. a -> a -> a
caseWordSize_32_64 Int
8 Int
16)


{-# INLINE wholeWordHex_ #-}
wholeWordHex_
  :: (Bits a, Num a)
  => Int
  -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ :: forall a overflow.
(Bits a, Num a) =>
Int -> overflow -> a -> Int -> Parser overflow (a, Int)
wholeWordHex_ Int
len overflow
overflow = \a
v Int
n -> do
  State Flow a
r Int
n' <- a -> Int -> Parser (State a) (State a)
forall {t} {b}. (Num t, Bits t) => t -> Int -> Parser (State t) b
go a
v Int
n Parser (State a) (State a)
-> (State a -> Parser overflow (State a))
-> Parser overflow (State a)
forall e a x. Parser e a -> (e -> Parser x a) -> Parser x a
`catch` State a -> Parser overflow (State a)
forall a. a -> Parser overflow a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Int64 -> Parser overflow ()
forall never. Int64 -> Parser never ()
unsafeSkipEndOr (Int64 -> Parser overflow ()) -> Int64 -> Parser overflow ()
forall a b. (a -> b) -> a -> b
$ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
  case Flow a
r of
    Number a
v' -> (a, Int) -> Parser overflow (a, Int)
forall a. a -> Parser overflow a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
v', Int
n')
    Flow a
Overflow  -> overflow -> Parser overflow (a, Int)
forall e a. e -> Parser e a
err overflow
overflow
  where
    go :: t -> Int -> Parser (State t) b
go !t
v !Int
n = do
      Word8
w <- State t -> Parser (State t) Word8
forall end. end -> Parser end Word8
word8 (State t -> Parser (State t) Word8)
-> State t -> Parser (State t) Word8
forall a b. (a -> b) -> a -> b
$ Flow t -> Int -> State t
forall a. Flow a -> Int -> State a
State (t -> Flow t
forall a. a -> Flow a
Number t
v) Int
n
      case Word8 -> Maybe Word8
hex Word8
w of
        Maybe Word8
Nothing -> State t -> Parser (State t) b
forall e a. e -> Parser e a
err (State t -> Parser (State t) b) -> State t -> Parser (State t) b
forall a b. (a -> b) -> a -> b
$ Flow t -> Int -> State t
forall a. Flow a -> Int -> State a
State (t -> Flow t
forall a. a -> Flow a
Number t
v) Int
n
        Just Word8
i  -> let !v' :: t
v' = t -> Int -> t
forall a. Bits a => a -> Int -> a
unsafeShiftL t
v Int
4 t -> t -> t
forall a. Num a => a -> a -> a
+ Word8 -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i
                       n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

                   in if Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len
                        then t -> Int -> Parser (State t) b
go t
v' Int
n'
                        else t -> Int -> Parser (State t) b
forall {a} {b}. a -> Int -> Parser (State a) b
checkOverflow t
v' Int
n'

    checkOverflow :: a -> Int -> Parser (State a) b
checkOverflow !a
v !Int
n = do
      Word8
w <- State a -> Parser (State a) Word8
forall end. end -> Parser end Word8
word8 (State a -> Parser (State a) Word8)
-> State a -> Parser (State a) Word8
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n

      let !(# Flow a
r #) = case Word8 -> Maybe Word8
hex Word8
w of
                       Maybe Word8
Nothing -> (# a -> Flow a
forall a. a -> Flow a
Number a
v #)
                       Just Word8
_  -> (# Flow a
forall a. Flow a
Overflow #)
      State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
r Int
n



-- | Intermediate representation of a signed integer.
newtype WholeInt word = WholeInt
                          word   -- ^ Number as an unsigned integer.
                        deriving Int -> WholeInt word -> ShowS
[WholeInt word] -> ShowS
WholeInt word -> String
(Int -> WholeInt word -> ShowS)
-> (WholeInt word -> String)
-> ([WholeInt word] -> ShowS)
-> Show (WholeInt word)
forall word. Show word => Int -> WholeInt word -> ShowS
forall word. Show word => [WholeInt word] -> ShowS
forall word. Show word => WholeInt word -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall word. Show word => Int -> WholeInt word -> ShowS
showsPrec :: Int -> WholeInt word -> ShowS
$cshow :: forall word. Show word => WholeInt word -> String
show :: WholeInt word -> String
$cshowList :: forall word. Show word => [WholeInt word] -> ShowS
showList :: [WholeInt word] -> ShowS
Show

-- | Convert the intermediate representation into an 'Int8'.
wholeToInt8 :: Sign -> WholeInt Word8 -> Int8
wholeToInt8 :: Sign -> WholeInt Word8 -> Int8
wholeToInt8 = Sign -> WholeInt Word8 -> Int8
forall w i. (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_

-- | Convert the intermediate representation into an 'Int16'.
wholeToInt16 :: Sign -> WholeInt Word16 -> Int16
wholeToInt16 :: Sign -> WholeInt Word16 -> Int16
wholeToInt16 = Sign -> WholeInt Word16 -> Int16
forall w i. (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_

-- | Convert the intermediate representation into an 'Int32'.
wholeToInt32 :: Sign -> WholeInt Word32 -> Int32
wholeToInt32 :: Sign -> WholeInt Word32 -> Int32
wholeToInt32 = Sign -> WholeInt Word32 -> Int32
forall w i. (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_

-- | Convert the intermediate representation into an 'Int64'.
wholeToInt64 :: Sign -> WholeInt Word64 -> Int64
wholeToInt64 :: Sign -> WholeInt Word64 -> Int64
wholeToInt64 = Sign -> WholeInt Word64 -> Int64
forall w i. (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_

-- | Convert the intermediate representation into an 'Int'.
wholeToInt :: Sign -> WholeInt Word -> Int
wholeToInt :: Sign -> WholeInt Word -> Int
wholeToInt = Sign -> WholeInt Word -> Int
forall w i. (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_

{-# INLINE wholeToInt_ #-}
wholeToInt_ :: (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_ :: forall w i. (Integral w, Num i) => Sign -> WholeInt w -> i
wholeToInt_ Sign
Plus  (WholeInt w
w) = w -> i
forall a b. (Integral a, Num b) => a -> b
fromIntegral w
w
wholeToInt_ Sign
Minus (WholeInt w
w) = w -> i
forall a b. (Integral a, Num b) => a -> b
fromIntegral (w -> w
forall a. Num a => a -> a
negate w
w)



-- | Consume up to 3 decimal digits into an 'Int8'-compatible container.
wholeInt8Dec
  :: overflow
  -> Sign
  -> WholeInt Word8
  -> Int            -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (WholeInt Word8, Int)
wholeInt8Dec :: forall overflow.
overflow
-> Sign
-> WholeInt Word8
-> Int
-> Parser overflow (WholeInt Word8, Int)
wholeInt8Dec = (Int, Word8, Word8)
-> overflow
-> Sign
-> WholeInt Word8
-> Int
-> Parser overflow (WholeInt Word8, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a)
-> overflow
-> Sign
-> WholeInt a
-> Int
-> Parser overflow (WholeInt a, Int)
wholeIntDec_ (Int, Word8, Word8)
forall a. Num a => (Int, a, a)
i8

-- | Consume up to 5 decimal digits into an 'Int16'-compatible container.
wholeInt16Dec
  :: overflow
  -> Sign
  -> WholeInt Word16
  -> Int             -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (WholeInt Word16, Int)
wholeInt16Dec :: forall overflow.
overflow
-> Sign
-> WholeInt Word16
-> Int
-> Parser overflow (WholeInt Word16, Int)
wholeInt16Dec = (Int, Word16, Word16)
-> overflow
-> Sign
-> WholeInt Word16
-> Int
-> Parser overflow (WholeInt Word16, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a)
-> overflow
-> Sign
-> WholeInt a
-> Int
-> Parser overflow (WholeInt a, Int)
wholeIntDec_ (Int, Word16, Word16)
forall a. Num a => (Int, a, a)
i16

-- | Consume up to 10 decimal digits into an 'Int32'-compatible container.
wholeInt32Dec
  :: overflow
  -> Sign
  -> WholeInt Word32
  -> Int             -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (WholeInt Word32, Int)
wholeInt32Dec :: forall overflow.
overflow
-> Sign
-> WholeInt Word32
-> Int
-> Parser overflow (WholeInt Word32, Int)
wholeInt32Dec = (Int, Word32, Word32)
-> overflow
-> Sign
-> WholeInt Word32
-> Int
-> Parser overflow (WholeInt Word32, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a)
-> overflow
-> Sign
-> WholeInt a
-> Int
-> Parser overflow (WholeInt a, Int)
wholeIntDec_ (Int, Word32, Word32)
forall a. Num a => (Int, a, a)
i32

-- | Consume up to 19 decimal digits into an 'Int64'-compatible container.
wholeInt64Dec
  :: overflow
  -> Sign
  -> WholeInt Word64
  -> Int             -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (WholeInt Word64, Int)
wholeInt64Dec :: forall overflow.
overflow
-> Sign
-> WholeInt Word64
-> Int
-> Parser overflow (WholeInt Word64, Int)
wholeInt64Dec = (Int, Word64, Word64)
-> overflow
-> Sign
-> WholeInt Word64
-> Int
-> Parser overflow (WholeInt Word64, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a)
-> overflow
-> Sign
-> WholeInt a
-> Int
-> Parser overflow (WholeInt a, Int)
wholeIntDec_ (Int, Word64, Word64)
forall a. Num a => (Int, a, a)
i64

-- | Consume up to 10 or 19 decimal digits (depending on current platform's integer size)
--   into an 'Int'-compatible container.
wholeIntDec
  :: overflow
  -> Sign
  -> WholeInt Word
  -> Int           -- ^ Number of decimal digits consumed by this number.
  -> Parser overflow (WholeInt Word, Int)
wholeIntDec :: forall overflow.
overflow
-> Sign
-> WholeInt Word
-> Int
-> Parser overflow (WholeInt Word, Int)
wholeIntDec = (Int, Word, Word)
-> overflow
-> Sign
-> WholeInt Word
-> Int
-> Parser overflow (WholeInt Word, Int)
forall a overflow.
(Ord a, Num a) =>
(Int, a, a)
-> overflow
-> Sign
-> WholeInt a
-> Int
-> Parser overflow (WholeInt a, Int)
wholeIntDec_ ((Int, Word, Word) -> (Int, Word, Word) -> (Int, Word, Word)
forall a. a -> a -> a
caseWordSize_32_64 (Int, Word, Word)
forall a. Num a => (Int, a, a)
i32 (Int, Word, Word)
forall a. Num a => (Int, a, a)
i64)

{-# INLINE wholeIntDec_ #-}
wholeIntDec_
  :: (Ord a, Num a)
  => (Int, a, a)
  -> overflow -> Sign -> WholeInt a -> Int -> Parser overflow (WholeInt a, Int)
wholeIntDec_ :: forall a overflow.
(Ord a, Num a) =>
(Int, a, a)
-> overflow
-> Sign
-> WholeInt a
-> Int
-> Parser overflow (WholeInt a, Int)
wholeIntDec_ (Int
len, a
bound, a
tip) overflow
overflow Sign
sign = \(WholeInt a
v) Int
n -> do
  State Flow a
r Int
n' <- a -> Int -> Parser (State a) (State a)
forall {b}. a -> Int -> Parser (State a) b
go a
v Int
n Parser (State a) (State a)
-> (State a -> Parser overflow (State a))
-> Parser overflow (State a)
forall e a x. Parser e a -> (e -> Parser x a) -> Parser x a
`catch` State a -> Parser overflow (State a)
forall a. a -> Parser overflow a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Int64 -> Parser overflow ()
forall never. Int64 -> Parser never ()
unsafeSkipEndOr (Int64 -> Parser overflow ()) -> Int64 -> Parser overflow ()
forall a b. (a -> b) -> a -> b
$ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
  case Flow a
r of
    Number a
v' -> (WholeInt a, Int) -> Parser overflow (WholeInt a, Int)
forall a. a -> Parser overflow a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> WholeInt a
forall word. word -> WholeInt word
WholeInt a
v', Int
n')
    Flow a
Overflow  -> overflow -> Parser overflow (WholeInt a, Int)
forall e a. e -> Parser e a
err overflow
overflow
  where
    go :: a -> Int -> Parser (State a) b
go !a
v !Int
n = do
      Word8
w <- State a -> Parser (State a) Word8
forall end. end -> Parser end Word8
word8 (State a -> Parser (State a) Word8)
-> State a -> Parser (State a) Word8
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n
      case Word8 -> Maybe Word8
dec Word8
w of
        Maybe Word8
Nothing -> State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n
        Just Word8
i  -> let !v' :: a
v' = a
v a -> a -> a
forall a. Num a => a -> a -> a
* a
10 a -> a -> a
forall a. Num a => a -> a -> a
+ Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i
                       n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

                   in if Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
len
                        then a -> Int -> Parser (State a) b
go a
v' Int
n'
                        else case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
v a
bound of
                               Ordering
LT -> a -> Int -> Parser (State a) b
forall {a} {b}. a -> Int -> Parser (State a) b
checkOverflow a
v' Int
n'

                               Ordering
EQ -> if Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= case Sign
sign of
                                                            Sign
Plus  -> a
tip
                                                            Sign
Minus -> a
tip a -> a -> a
forall a. Num a => a -> a -> a
+ a
1

                                       then a -> Int -> Parser (State a) b
forall {a} {b}. a -> Int -> Parser (State a) b
checkOverflow a
v' Int
n'
                                       else State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
forall a. Flow a
Overflow Int
n

                               Ordering
GT -> State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
forall a. Flow a
Overflow Int
n

    checkOverflow :: a -> Int -> Parser (State a) b
checkOverflow !a
v !Int
n = do
      Word8
w <- State a -> Parser (State a) Word8
forall end. end -> Parser end Word8
word8 (State a -> Parser (State a) Word8)
-> State a -> Parser (State a) Word8
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State (a -> Flow a
forall a. a -> Flow a
Number a
v) Int
n

      let !(# Flow a
r #) = case Word8 -> Maybe Word8
dec Word8
w of
                       Maybe Word8
Nothing -> (# a -> Flow a
forall a. a -> Flow a
Number a
v #)
                       Just Word8
_  -> (# Flow a
forall a. Flow a
Overflow #)
      State a -> Parser (State a) b
forall e a. e -> Parser e a
err (State a -> Parser (State a) b) -> State a -> Parser (State a) b
forall a b. (a -> b) -> a -> b
$ Flow a -> Int -> State a
forall a. Flow a -> Int -> State a
State Flow a
r Int
n