bookhound-0.1.10.0: src/Bookhound/Parsers/Number.hs
module Bookhound.Parsers.Number (int, double, posInt, negInt, unsignedInt, hexInt, octInt, intLike) where
import Bookhound.Parser (ParseError (..), Parser, errorParser,
withError)
import Bookhound.ParserCombinators (IsMatch (..), (<|>), (>>>), (|+), (|?))
import Bookhound.Parsers.Char (dash, digit, dot, plus)
hexInt :: Parser Integer
hexInt = withError "Hex Int"
$ read <$> (is "0x" >>> ((digit <|> oneOf ['A' .. 'F'] <|> oneOf ['a' .. 'f']) |+))
octInt :: Parser Integer
octInt = withError "Oct Int"
$ read <$> (is "0o" >>> (oneOf ['0' .. '7'] |+))
unsignedInt :: Parser Integer
unsignedInt = withError "Unsigned Int"
$ read <$> (digit |+)
posInt :: Parser Integer
posInt = withError "Positive Int"
$ read <$> (plus |?) >>> (digit |+)
negInt :: Parser Integer
negInt = withError "Negative Int"
$ read <$> dash >>> (digit |+)
int :: Parser Integer
int = withError "Int" $ negInt <|> posInt
intLike :: Parser Integer
intLike = parser <|> int
where
parser = do n1 <- show <$> int
n2 <- show <$> (dot *> unsignedInt)
expNum <- oneOf ['e', 'E'] *> int
if length n1 + length n2 <= fromInteger expNum then
pure . read $ n1 <> "." <> n2 <> "E" <> show expNum
else
errorParser $ NoMatch "Int Like"
double :: Parser Double
double = withError "Double"
$ read <$> int >>> (decimals |?) >>> (expn |?) where
decimals = dot >>> unsignedInt
expn = oneOf ['e', 'E'] >>> int