{-# OPTIONS_GHC -Wall -fwarn-tabs #-}
{-# LANGUAGE BangPatterns #-}
module Data.ByteString.Lex.Internal
(
isNotPeriod
, isNotE
, isDecimal
, isDecimalZero
, toDigit
, addDigit
, numDigits
, numTwoPowerDigits
, numDecimalDigits
) where
import Data.Word (Word8, Word64)
import Data.Bits (Bits(shiftR))
{-# INLINE isNotPeriod #-}
isNotPeriod :: Word8 -> Bool
isNotPeriod :: Word8 -> Bool
isNotPeriod Word8
w = Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
0x2E
{-# INLINE isNotE #-}
isNotE :: Word8 -> Bool
isNotE :: Word8 -> Bool
isNotE Word8
w = Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
0x65 Bool -> Bool -> Bool
&& Word8
w forall a. Eq a => a -> a -> Bool
/= Word8
0x45
{-# INLINE isDecimal #-}
isDecimal :: Word8 -> Bool
isDecimal :: Word8 -> Bool
isDecimal Word8
w = Word8
0x39 forall a. Ord a => a -> a -> Bool
>= Word8
w Bool -> Bool -> Bool
&& Word8
w forall a. Ord a => a -> a -> Bool
>= Word8
0x30
{-# INLINE isDecimalZero #-}
isDecimalZero :: Word8 -> Bool
isDecimalZero :: Word8 -> Bool
isDecimalZero Word8
w = Word8
w forall a. Eq a => a -> a -> Bool
== Word8
0x30
{-# INLINE toDigit #-}
toDigit :: (Integral a) => Word8 -> a
toDigit :: forall a. Integral a => Word8 -> a
toDigit Word8
w = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
w forall a. Num a => a -> a -> a
- Word8
0x30)
{-# INLINE addDigit #-}
addDigit :: Int -> Word8 -> Int
addDigit :: Int -> Word8 -> Int
addDigit Int
n Word8
w = Int
n forall a. Num a => a -> a -> a
* Int
10 forall a. Num a => a -> a -> a
+ forall a. Integral a => Word8 -> a
toDigit Word8
w
numDigits :: Integer -> Integer -> Int
{-# INLINE numDigits #-}
numDigits :: Integer -> Integer -> Int
numDigits !Integer
b0 !Integer
n0
| Integer
b0 forall a. Ord a => a -> a -> Bool
<= Integer
1 = forall a. HasCallStack => [Char] -> a
error ([Char]
_numDigits forall a. [a] -> [a] -> [a]
++ [Char]
_nonpositiveBase)
| Integer
n0 forall a. Ord a => a -> a -> Bool
< Integer
0 = forall a. HasCallStack => [Char] -> a
error ([Char]
_numDigits forall a. [a] -> [a] -> [a]
++ [Char]
_negativeNumber)
| Bool
otherwise = Int
1 forall a. Num a => a -> a -> a
+ forall a b. (a, b) -> a
fst (forall {a} {a}. (Integral a, Num a) => a -> a -> (a, a)
ilog Integer
b0 Integer
n0)
where
ilog :: a -> a -> (a, a)
ilog !a
b !a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
b = (a
0, a
n)
| a
r forall a. Ord a => a -> a -> Bool
< a
b = ((,) forall a b. (a -> b) -> a -> b
$! a
2forall a. Num a => a -> a -> a
*a
e) a
r
| Bool
otherwise = ((,) forall a b. (a -> b) -> a -> b
$! a
2forall a. Num a => a -> a -> a
*a
eforall a. Num a => a -> a -> a
+a
1) forall a b. (a -> b) -> a -> b
$! (a
r forall a. Integral a => a -> a -> a
`quot` a
b)
where
(a
e, a
r) = a -> a -> (a, a)
ilog (a
bforall a. Num a => a -> a -> a
*a
b) a
n
numTwoPowerDigits :: (Integral a, Bits a) => Int -> a -> Int
{-# INLINE numTwoPowerDigits #-}
numTwoPowerDigits :: forall a. (Integral a, Bits a) => Int -> a -> Int
numTwoPowerDigits !Int
p !a
n0
| Int
p forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. HasCallStack => [Char] -> a
error ([Char]
_numTwoPowerDigits forall a. [a] -> [a] -> [a]
++ [Char]
_nonpositiveBase)
| a
n0 forall a. Ord a => a -> a -> Bool
< a
0 = forall a. HasCallStack => [Char] -> a
error ([Char]
_numTwoPowerDigits forall a. [a] -> [a] -> [a]
++ [Char]
_negativeNumber)
| a
n0 forall a. Eq a => a -> a -> Bool
== a
0 = Int
1
| Bool
otherwise = forall {t} {t}. (Ord t, Num t, Num t, Bits t) => t -> t -> t
go Int
0 a
n0
where
go :: t -> t -> t
go !t
d !t
n
| t
n forall a. Ord a => a -> a -> Bool
> t
0 = t -> t -> t
go (t
dforall a. Num a => a -> a -> a
+t
1) (t
n forall a. Bits a => a -> Int -> a
`shiftR` Int
p)
| Bool
otherwise = t
d
numDecimalDigits :: (Integral a) => a -> Int
{-# INLINE numDecimalDigits #-}
numDecimalDigits :: forall a. Integral a => a -> Int
numDecimalDigits a
n0
| a
n0 forall a. Ord a => a -> a -> Bool
< a
0 = forall a. HasCallStack => [Char] -> a
error ([Char]
_numDecimalDigits forall a. [a] -> [a] -> [a]
++ [Char]
_negativeNumber)
| a
n0 forall a. Ord a => a -> a -> Bool
> a
limit = Integer -> Integer -> Int
numDigits Integer
10 (forall a. Integral a => a -> Integer
toInteger a
n0)
| Bool
otherwise = forall {t} {t}. (Num t, Integral t) => t -> t -> t
go Int
1 (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n0 :: Word64)
where
limit :: a
limit = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Word64)
fin :: a -> a -> a
fin a
n a
bound = if a
n forall a. Ord a => a -> a -> Bool
>= a
bound then a
1 else a
0
go :: t -> t -> t
go !t
k !t
n
| t
n forall a. Ord a => a -> a -> Bool
< t
10 = t
k
| t
n forall a. Ord a => a -> a -> Bool
< t
100 = t
k forall a. Num a => a -> a -> a
+ t
1
| t
n forall a. Ord a => a -> a -> Bool
< t
1000 = t
k forall a. Num a => a -> a -> a
+ t
2
| t
n forall a. Ord a => a -> a -> Bool
< t
1000000000000 =
t
k forall a. Num a => a -> a -> a
+ if t
n forall a. Ord a => a -> a -> Bool
< t
100000000
then if t
n forall a. Ord a => a -> a -> Bool
< t
1000000
then if t
n forall a. Ord a => a -> a -> Bool
< t
10000
then t
3
else t
4 forall a. Num a => a -> a -> a
+ forall {a} {a}. (Ord a, Num a) => a -> a -> a
fin t
n t
100000
else t
6 forall a. Num a => a -> a -> a
+ forall {a} {a}. (Ord a, Num a) => a -> a -> a
fin t
n t
10000000
else if t
n forall a. Ord a => a -> a -> Bool
< t
10000000000
then t
8 forall a. Num a => a -> a -> a
+ forall {a} {a}. (Ord a, Num a) => a -> a -> a
fin t
n t
1000000000
else t
10 forall a. Num a => a -> a -> a
+ forall {a} {a}. (Ord a, Num a) => a -> a -> a
fin t
n t
100000000000
| Bool
otherwise = t -> t -> t
go (t
k forall a. Num a => a -> a -> a
+ t
12) (t
n forall a. Integral a => a -> a -> a
`quot` t
1000000000000)
_numDigits :: String
_numDigits :: [Char]
_numDigits = [Char]
"numDigits"
{-# NOINLINE _numDigits #-}
_numTwoPowerDigits :: String
_numTwoPowerDigits :: [Char]
_numTwoPowerDigits = [Char]
"numTwoPowerDigits"
{-# NOINLINE _numTwoPowerDigits #-}
_numDecimalDigits :: String
_numDecimalDigits :: [Char]
_numDecimalDigits = [Char]
"numDecimalDigits"
{-# NOINLINE _numDecimalDigits #-}
_nonpositiveBase :: String
_nonpositiveBase :: [Char]
_nonpositiveBase = [Char]
": base must be greater than one"
{-# NOINLINE _nonpositiveBase #-}
_negativeNumber :: String
_negativeNumber :: [Char]
_negativeNumber = [Char]
": number must be non-negative"
{-# NOINLINE _negativeNumber #-}