packages feed

bookhound-0.1.3.0: src/Parsers/Number.hs

module Parsers.Number (int, double, posInt, negInt, unsignedInt, hexInt, octInt, intLike) where

import Parser (Parser, errorParser, ParseError(..))
import ParserCombinators (IsMatch(..), (>>>), (<|>), (|+), (|?))
import Parsers.Char (digit, dot, dash, plus)


hexInt :: Parser Integer
hexInt = read <$> (is "0x" >>> ((digit <|> oneOf ['A' .. 'F'] <|> oneOf ['a' .. 'f']) |+))

octInt :: Parser Integer
octInt = read <$> (is "0o" >>> (oneOf ['0' .. '7'] |+))

unsignedInt :: Parser Integer
unsignedInt = read <$> (digit |+)

posInt :: Parser Integer
posInt = read <$> (plus |?) >>> (digit |+)

negInt :: Parser Integer
negInt = read <$> dash >>> (digit |+)

int :: Parser Integer
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 "intLike"


double :: Parser Double
double = read <$> int >>> (decimals |?) >>> (expn |?) where

  decimals = dot >>> unsignedInt
  expn      = oneOf ['e', 'E'] >>> int