git.iko.soy/typeable/attoparsec
on master help sign in
Fix asciiCI performance

Fix #135

commit1e7703340b4485e65684584dff574fa57a9e88f2 authorKusanagi Kouichi <slash@ac.auone-net.jp> dateFri 12 Jan 2018, 01:25 (9 years ago) parent20a6721
1 file changed+9−8
Data/Attoparsec/Text/Internal.hs+9−8
Data/Attoparsec/Text/Internal.hs+9−8
@@ -75,7 +75,7 @@ import Data.Attoparsec.Internal
7575import Data.Attoparsec.Internal.Types hiding (Parser, Failure, Success)
7676import qualified Data.Attoparsec.Text.Buffer as Buf
7777import Data.Attoparsec.Text.Buffer (Buffer, buffer)
78−import Data.Char (chr, ord)
78+import Data.Char (isAsciiUpper, isAsciiLower, toUpper, toLower)
7979import Data.List (intercalate)
8080import Data.String (IsString(..))
8181import Data.Text.Internal (Text(..))
@@ -225,15 +225,16 @@ stringCI s = go 0
225225
226226-- | Satisfy a literal string, ignoring case for characters in the ASCII range.
227227asciiCI :: Text -> Parser Text
228−asciiCI s = string_ (stringSuspended asciiToLower) asciiToLower s
229− where
230− asciiToLower = T.map f
231− where
232− offset = ord 'a' - ord 'A'
233− f c | 'A' <= c && c <= 'Z' = chr (ord c + offset)
234− | otherwise = c
228+asciiCI s = fmap fst $ match $ T.foldr ((*>) . asciiCharCI) (pure ()) s
235229{-# INLINE asciiCI #-}
236230
231+asciiCharCI :: Char -> Parser Char
232+asciiCharCI c
233+ | isAsciiUpper c = char c <|> char (toLower c)
234+ | isAsciiLower c = char c <|> char (toUpper c)
235+ | otherwise = char c
236+{-# INLINE asciiCharCI #-}
237+
237238-- | Skip past input for as long as the predicate returns 'True'.
238239skipWhile :: (Char -> Bool) -> Parser ()
239240skipWhile p = go