@@ -1,4 +1,4 @@
1−{-# LANGUAGE FlexibleInstances #-}
1+{-# LANGUAGE BangPatterns, FlexibleInstances #-}
22{-# OPTIONS_GHC -fno-warn-orphans #-}
33
44-- |
@@ -99,9 +99,10 @@ import Data.Attoparsec.Internal (Parser, (<?>))
9999import Data.Attoparsec.Number (Number(..))
100100import Data.Bits (Bits, (.|.), shiftL)
101101import Data.ByteString.Internal (c2w, w2c)
102+import Data.Int (Int8, Int16, Int32, Int64)
102103import Data.Ratio ((%))
103104import Data.String (IsString(..))
104−import Data.Word (Word8)
105+import Data.Word (Word8, Word16, Word32, Word64, Word)
105106import Prelude hiding (takeWhile)
106107import qualified Data.Attoparsec as A
107108import qualified Data.Attoparsec.Internal as I
@@ -337,7 +338,6 @@ isHorizontalSpace w = w == 32 || w == 9
337338--
338339-- This parser does not accept a leading @\"0x\"@ string.
339340hexadecimal :: (Integral a, Bits a) => Parser a
340−{-# SPECIALISE hexadecimal :: Parser Int #-}
341341hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit
342342 where
343343 isHexDigit w = (w >= 48 && w <= 57) ||
@@ -346,25 +346,48 @@ hexadecimal = B8.foldl' step 0 `fmap` I.takeWhile1 isHexDigit
346346 step a w | w >= 48 && w <= 57 = (a `shiftL` 4) .|. fromIntegral (w - 48)
347347 | w >= 97 = (a `shiftL` 4) .|. fromIntegral (w - 87)
348348 | 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 #-}
349360
350361-- | Parse and decode an unsigned decimal number.
351362decimal :: Integral a => Parser a
352−{-# SPECIALISE decimal :: Parser Int #-}
353−{-# SPECIALISE decimal :: Parser Integer #-}
354363decimal = B8.foldl' step 0 `fmap` I.takeWhile1 isDig
355364 where isDig w = w >= 48 && w <= 57
356365 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 #-}
357377
358378-- | Parse a number with an optional leading @\'+\'@ or @\'-\'@ sign
359379-- character.
360380signed :: Num a => Parser a -> Parser a
361381{-# 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 #-}
362387signed p = (negate <$> (char8 '-' *> p))
363388 <|> (char8 '+' *> p)
364389 <|> p
365390
366−data T = T !Integer !Int
367−
368391-- | Parse a rational number.
369392--
370393-- This parser accepts an optional leading sign character, followed by
@@ -391,6 +414,8 @@ data T = T !Integer !Int
391414-- >rational "3e" == Done 3.0 "e"
392415rational :: Fractional a => Parser a
393416{-# SPECIALIZE rational :: Parser Double #-}
417+{-# SPECIALIZE rational :: Parser Float #-}
418+{-# SPECIALIZE rational :: Parser Rational #-}
394419rational = floaty $ \real frac fracDenom -> fromRational $
395420 real % 1 + frac % fracDenom
396421
@@ -429,12 +454,15 @@ number = floaty $ \real frac fracDenom ->
429454 else D (asDouble real frac fracDenom)
430455{-# INLINE number #-}
431456
457+data T = T !Integer !Int
458+
432459floaty :: Fractional a => (Integer -> Integer -> Integer -> a) -> Parser a
433460{-# INLINE floaty #-}
434461floaty f = do
435462 let minus = 45
436463 plus = 43
437− sign <- I.satisfy (\c -> c == minus || c == plus) <|> return plus
464+ !positive <- ((== plus) <$> I.satisfy (\c -> c == minus || c == plus)) <|>
465+ return True
438466 real <- decimal
439467 let tryFraction = do
440468 let dot = 46
@@ -455,7 +483,6 @@ floaty f = do
455483 else if power == 0
456484 then f real fraction (10 ^ fracDigits)
457485 else f real fraction (10 ^ fracDigits) * (10 ^^ power)
458− return $ if sign == plus
486+ return $ if positive
459487 then n
460488 else -n
461−