@@ -1,4 +1,4 @@
1−{-# LANGUAGE FlexibleInstances #-}
1+{-# LANGUAGE BangPatterns, FlexibleInstances #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
@@ -99,9 +99,10 @@ import Data.Attoparsec.Internal (Parser, (<?>))
99import Data.Attoparsec.Number (Number(..))
99import Data.Attoparsec.Number (Number(..))
100import Data.Bits (Bits, (.|.), shiftL)
100import Data.Bits (Bits, (.|.), shiftL)
101import Data.ByteString.Internal (c2w, w2c)
101import Data.ByteString.Internal (c2w, w2c)
102+import Data.Int (Int8, Int16, Int32, Int64)
102import Data.Ratio ((%))
103import Data.Ratio ((%))
103import Data.String (IsString(..))
104import Data.String (IsString(..))
104−import Data.Word (Word8)
105+import Data.Word (Word8, Word16, Word32, Word64, Word)
105import Prelude hiding (takeWhile)
106import Prelude hiding (takeWhile)
106import qualified Data.Attoparsec as A
107import qualified Data.Attoparsec as A
107import qualified Data.Attoparsec.Internal as I
108import qualified Data.Attoparsec.Internal as I
@@ -337,7 +338,6 @@ isHorizontalSpace w = w == 32 || w == 9
338-- This parser does not accept a leading @\"0x\"@ string.
339-- This parser does not accept a leading @\"0x\"@ string.
339hexadecimal :: (Integral a, Bits a) => Parser a
340hexadecimal :: (Integral a, Bits a) => Parser a
340−{-# SPECIALISE hexadecimal :: Parser Int #-}
341hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit
341hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit
343 isHexDigit w = (w >= 48 && w <= 57) ||
343 isHexDigit w = (w >= 48 && w <= 57) ||
@@ -346,25 +346,48 @@ hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit
346 step a w | w >= 48 && w <= 57 = (a `shiftL` 4) .|. fromIntegral (w - 48)
346 step a w | w >= 48 && w <= 57 = (a `shiftL` 4) .|. fromIntegral (w - 48)
347 | w >= 97 = (a `shiftL` 4) .|. fromIntegral (w - 87)
347 | w >= 97 = (a `shiftL` 4) .|. fromIntegral (w - 87)
348 | otherwise = (a `shiftL` 4) .|. fromIntegral (w - 55)
348 | otherwise = (a `shiftL` 4) .|. fromIntegral (w - 55)
349+{-# SPECIALISE hexadecimal :: Parser Int #-}
350+{-# SPECIALISE hexadecimal :: Parser Int8 #-}
351+{-# SPECIALISE hexadecimal :: Parser Int16 #-}
352+{-# SPECIALISE hexadecimal :: Parser Int32 #-}
353+{-# SPECIALISE hexadecimal :: Parser Int64 #-}
354+{-# SPECIALISE hexadecimal :: Parser Integer #-}
355+{-# SPECIALISE hexadecimal :: Parser Word #-}
356+{-# SPECIALISE hexadecimal :: Parser Word8 #-}
357+{-# SPECIALISE hexadecimal :: Parser Word16 #-}
358+{-# SPECIALISE hexadecimal :: Parser Word32 #-}
359+{-# SPECIALISE hexadecimal :: Parser Word64 #-}
350-- | Parse and decode an unsigned decimal number.
361-- | Parse and decode an unsigned decimal number.
351decimal :: Integral a => Parser a
362decimal :: Integral a => Parser a
352−{-# SPECIALISE decimal :: Parser Int #-}
353−{-# SPECIALISE decimal :: Parser Integer #-}
354decimal = B8.foldl' step 0 `fmap` I.takeWhile1 isDig
363decimal = B8.foldl' step 0 `fmap` I.takeWhile1 isDig
355 where isDig w = w >= 48 && w <= 57
364 where isDig w = w >= 48 && w <= 57
356 step a w = a * 10 + fromIntegral (w - 48)
365 step a w = a * 10 + fromIntegral (w - 48)
366+{-# SPECIALISE decimal :: Parser Int #-}
367+{-# SPECIALISE decimal :: Parser Int8 #-}
368+{-# SPECIALISE decimal :: Parser Int16 #-}
369+{-# SPECIALISE decimal :: Parser Int32 #-}
370+{-# SPECIALISE decimal :: Parser Int64 #-}
371+{-# SPECIALISE decimal :: Parser Integer #-}
372+{-# SPECIALISE decimal :: Parser Word #-}
373+{-# SPECIALISE decimal :: Parser Word8 #-}
374+{-# SPECIALISE decimal :: Parser Word16 #-}
375+{-# SPECIALISE decimal :: Parser Word32 #-}
376+{-# SPECIALISE decimal :: Parser Word64 #-}
358-- | Parse a number with an optional leading @\'+\'@ or @\'-\'@ sign
378-- | Parse a number with an optional leading @\'+\'@ or @\'-\'@ sign
359-- character.
379-- character.
360signed :: Num a => Parser a -> Parser a
380signed :: Num a => Parser a -> Parser a
361{-# SPECIALISE signed :: Parser Int -> Parser Int #-}
381{-# SPECIALISE signed :: Parser Int -> Parser Int #-}
382+{-# SPECIALISE signed :: Parser Int8 -> Parser Int8 #-}
383+{-# SPECIALISE signed :: Parser Int16 -> Parser Int16 #-}
384+{-# SPECIALISE signed :: Parser Int32 -> Parser Int32 #-}
385+{-# SPECIALISE signed :: Parser Int64 -> Parser Int64 #-}
386+{-# SPECIALISE signed :: Parser Integer -> Parser Integer #-}
362signed p = (negate <$> (char8 '-' *> p))
387signed p = (negate <$> (char8 '-' *> p))
363 <|> (char8 '+' *> p)
388 <|> (char8 '+' *> p)
366−data T = T !Integer !Int
368-- | Parse a rational number.
391-- | Parse a rational number.
370-- This parser accepts an optional leading sign character, followed by
393-- This parser accepts an optional leading sign character, followed by
@@ -391,6 +414,8 @@ data T = T !Integer !Int
391-- >rational "3e" == Done 3.0 "e"
414-- >rational "3e" == Done 3.0 "e"
392rational :: Fractional a => Parser a
415rational :: Fractional a => Parser a
393{-# SPECIALIZE rational :: Parser Double #-}
416{-# SPECIALIZE rational :: Parser Double #-}
417+{-# SPECIALIZE rational :: Parser Float #-}
418+{-# SPECIALIZE rational :: Parser Rational #-}
394rational = floaty $ \real frac fracDenom -> fromRational $
419rational = floaty $ \real frac fracDenom -> fromRational $
395 real % 1 + frac % fracDenom
420 real % 1 + frac % fracDenom
@@ -429,12 +454,15 @@ number = floaty $ \real frac fracDenom ->
429 else D (asDouble real frac fracDenom)
454 else D (asDouble real frac fracDenom)
430{-# INLINE number #-}
455{-# INLINE number #-}
457+data T = T !Integer !Int
432floaty :: Fractional a => (Integer -> Integer -> Integer -> a) -> Parser a
459floaty :: Fractional a => (Integer -> Integer -> Integer -> a) -> Parser a
433{-# INLINE floaty #-}
460{-# INLINE floaty #-}
434floaty f = do
461floaty f = do
435 let minus = 45
462 let minus = 45
436 plus = 43
463 plus = 43
437− sign <- I.satisfy (\c -> c == minus || c == plus) <|> return plus
464+ !positive <- ((== plus) <$> I.satisfy (\c -> c == minus || c == plus)) <|>
438 real <- decimal
466 real <- decimal
439 let tryFraction = do
467 let tryFraction = do
440 let dot = 46
468 let dot = 46
@@ -455,7 +483,6 @@ floaty f = do
455 else if power == 0
483 else if power == 0
456 then f real fraction (10 ^ fracDigits)
484 then f real fraction (10 ^ fracDigits)
457 else f real fraction (10 ^ fracDigits) * (10 ^^ power)
485 else f real fraction (10 ^ fracDigits) * (10 ^^ power)
458− return $ if sign == plus
486+ return $ if positive