LslPlus-0.1.2: src/Language/Lsl/Internal/NumberParsing.hs
module Language.Lsl.Internal.NumberParsing(readHexFloat,readInt) where
import Data.Char(digitToInt)
import Text.ParserCombinators.Parsec(GenParser(..),(<|>),char,digit,hexDigit,many,many1,oneOf,option,parse,satisfy)
hexFloat =
do char '0'
oneOf "xX"
wholeDigits <- many1 hexDigit
let w = foldl (\ x y -> x * 16.0 + y) 0.0 $ map (fromIntegral . digitToInt) wholeDigits
frac <- option 0.0 fractionalPart
p <- expPart
return $ (w + frac) * p
fractionalPart =
do char '.'
digits <- many1 hexDigit
return $ foldr (\ x y -> (x + y) / 16.0) 0.0 $ map (fromIntegral . digitToInt) digits
expPart =
do oneOf "pP"
f <- option (2^) ((char '+' >> return (2^)) <|> (char '-' >> return ((1/).(2^))))
digits <- many1 digit
let exp = foldl (\ x y -> 10 * x + y) 0 $ map digitToInt digits
return $ f exp
hexFloatAndTail :: Fractional a => GenParser Char b [(a,String)]
hexFloatAndTail =
do v <- hexFloat
rest <- many (satisfy (const True))
return [(realToFrac v,rest)]
readHexFloat s =
case parse hexFloatAndTail "" s of
Left _ -> []
Right v -> v
hexInt =
do oneOf "xX"
digits <- many1 hexDigit
return $ foldl (\ x y -> x * 16 + y) 0 $ map digitToInt digits
decimalInt =
do digits <- many1 digit
return $ foldl (\ x y -> x * 10 + y) 0 $ map digitToInt digits
int = do char '0'
(hexInt <|> decimalInt <|> return 0)
<|> decimalInt
intAndTail =
do i <- int
rest <- many (satisfy (const True))
return (i,rest)
readInt s =
case parse intAndTail "" s of
Left _ -> []
Right v -> [v]