Commits

Bryan O'Sullivan  committed d286162

A few Lex performance improvements

  • Participants
  • Parent commits 856c626

Comments (0)

Files changed (1)

File Data/Text/Lex.hs

 -- | Read a decimal number.
 decimal :: Integral a => Lexer a
 {-# SPECIALIZE decimal :: Lexer Int #-}
+{-# SPECIALIZE decimal :: Lexer Integer #-}
 decimal txt
     | T.null h  = Left "no digits in input"
     | otherwise = Right (T.foldl' go 0 h, t)
 -- function is case insensitive.
 hexadecimal :: Integral a => Lexer a
 {-# SPECIALIZE hex :: Lexer Int #-}
+{-# SPECIALIZE hex :: Lexer Integer #-}
 hexadecimal txt
     | T.toLower h == "0x" = hex t
     | otherwise           = hex txt
 
 hex :: Integral a => Lexer a
 {-# SPECIALIZE hex :: Lexer Int #-}
+{-# SPECIALIZE hex :: Lexer Integer #-}
 hex txt
     | T.null h  = Left "no digits in input"
     | otherwise = Right (T.foldl' go 0 h, t)
 signed f = runP (signa (P f))
 
 signa :: Num a => Parser a -> Parser a
-{-# SPECIALIZE signa :: Parser Int -> Parser Int  #-}
+{-# SPECIALIZE signa :: Parser Int -> Parser Int #-}
+{-# SPECIALIZE signa :: Parser Integer -> Parser Integer #-}
 signa p = do
   sign <- perhaps '+' $ char (`elem` "-+")
   if sign == '+' then p else negate `liftM` p
     n <- P decimal
     return (n, digits)
   power <- perhaps 0 (char (`elem` "eE") >> signa (P decimal) :: Parser Int)
-  return $! fromRational ((real % 1 + fraction % (10 ^ fracDigits)) *
-                          (10 ^ power))
+  return $! if fraction == 0
+            then if power == 0
+                 then fromIntegral real
+                 else fromIntegral real * (10 ^^ power)
+            else fromRational $ if power == 0
+                 then real % 1 + fraction % (10 ^ fracDigits)
+                 else (real % 1 + fraction % (10 ^ fracDigits)) * (10 ^^ power)