git.iko.soy/typeable/attoparsec
on master help sign in
Add DeepSeq support and more specialisations.
commit8ad6d5fb29af24a241c75fa7474f3cd6361c329c authorBryan O'Sullivan <bos@serpentine.com> dateSun 20 Mar 2011, 11:10 (16 years ago) parent3598635
4 files changed+54−11
Data/Attoparsec/Char8.hs+37−10 Data/Attoparsec/Internal.hs+9−1 Data/Attoparsec/Number.hs+6 attoparsec.cabal+2
Data/Attoparsec/Char8.hs+37−10
@@ -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−
Data/Attoparsec/Internal.hs+9−1
@@ -65,6 +65,7 @@ module Data.Attoparsec.Internal
6565 ) where
6666
6767import Control.Applicative (Alternative(..), Applicative(..), (<$>))
68+import Control.DeepSeq (NFData(rnf))
6869import Control.Monad (MonadPlus(..), when)
6970import Data.Attoparsec.Combinator
7071import Data.Attoparsec.FastSet (charClass, memberWord8)
@@ -103,6 +104,12 @@ instance Show r => Show (Result r) where
103104 show (Partial _) = "Partial _"
104105 show (Done bs r) = "Done " ++ show bs ++ " " ++ show r
105106
107+instance (NFData r) => NFData (Result r) where
108+ rnf (Fail _ _ _) = ()
109+ rnf (Partial _) = ()
110+ rnf (Done _ r) = rnf r
111+ {-# INLINE rnf #-}
112+
106113fmapR :: (a -> b) -> Result a -> Result b
107114fmapR _ (Fail st stk msg) = Fail st stk msg
108115fmapR f (Partial k) = Partial (fmapR f . k)
@@ -330,7 +337,8 @@ storable = hack undefined
330337takeWith :: Int -> (B.ByteString -> Bool) -> Parser B.ByteString
331338takeWith n p = do
332339 s <- ensure n
333− let (h,t) = B.splitAt n s
340+ let h = B.unsafeTake n s
341+ t = B.unsafeDrop n s
334342 if p h
335343 then put t >> return h
336344 else failDesc "takeWith"
Data/Attoparsec/Number.hs+6
@@ -15,6 +15,7 @@ module Data.Attoparsec.Number
1515 Number(..)
1616 ) where
1717
18+import Control.DeepSeq (NFData(rnf))
1819import Data.Data (Data)
1920import Data.Function (on)
2021import Data.Typeable (Typeable)
@@ -29,6 +30,11 @@ instance Show Number where
2930 show (I a) = show a
3031 show (D a) = show a
3132
33+instance NFData Number where
34+ rnf (I _) = ()
35+ rnf (D _) = ()
36+ {-# INLINE rnf #-}
37+
3238binop :: (Integer -> Integer -> a) -> (Double -> Double -> a)
3339 -> Number -> Number -> a
3440binop _ d (D a) (D b) = d a b
attoparsec.cabal+2
@@ -52,6 +52,8 @@ library
5252 else
5353 build-depends: base < 2.0
5454
55+ build-depends: deepseq
56+
5557 extensions: CPP
5658 exposed-modules: Data.Attoparsec
5759 Data.Attoparsec.Char8