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 :: Parser Integer hexInt = String -> Integer forall a. Read a => String -> a read (String -> Integer) -> Parser String -> Parser Integer forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (String -> Parser String forall a. IsMatch a => a -> Parser a is String "0x" Parser String -> Parser String -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> ((Parser Char digit Parser Char -> Parser Char -> Parser Char forall a. Parser a -> Parser a -> Parser a <|> String -> Parser Char forall a. IsMatch a => [a] -> Parser a oneOf [Char 'A' .. Char 'F'] Parser Char -> Parser Char -> Parser Char forall a. Parser a -> Parser a -> Parser a <|> String -> Parser Char forall a. IsMatch a => [a] -> Parser a oneOf [Char 'a' .. Char 'f']) Parser Char -> Parser String forall a. Parser a -> Parser [a] |+)) octInt :: Parser Integer octInt :: Parser Integer octInt = String -> Integer forall a. Read a => String -> a read (String -> Integer) -> Parser String -> Parser Integer forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (String -> Parser String forall a. IsMatch a => a -> Parser a is String "0o" Parser String -> Parser String -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> (String -> Parser Char forall a. IsMatch a => [a] -> Parser a oneOf [Char '0' .. Char '7'] Parser Char -> Parser String forall a. Parser a -> Parser [a] |+)) unsignedInt :: Parser Integer unsignedInt :: Parser Integer unsignedInt = String -> Integer forall a. Read a => String -> a read (String -> Integer) -> Parser String -> Parser Integer forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (Parser Char digit Parser Char -> Parser String forall a. Parser a -> Parser [a] |+) posInt :: Parser Integer posInt :: Parser Integer posInt = String -> Integer forall a. Read a => String -> a read (String -> Integer) -> Parser String -> Parser Integer forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (Parser Char plus Parser Char -> Parser (Maybe Char) forall a. Parser a -> Parser (Maybe a) |?) Parser (Maybe Char) -> Parser String -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> (Parser Char digit Parser Char -> Parser String forall a. Parser a -> Parser [a] |+) negInt :: Parser Integer negInt :: Parser Integer negInt = String -> Integer forall a. Read a => String -> a read (String -> Integer) -> Parser String -> Parser Integer forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parser Char dash Parser Char -> Parser String -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> (Parser Char digit Parser Char -> Parser String forall a. Parser a -> Parser [a] |+) int :: Parser Integer int :: Parser Integer int = Parser Integer negInt Parser Integer -> Parser Integer -> Parser Integer forall a. Parser a -> Parser a -> Parser a <|> Parser Integer posInt intLike :: Parser Integer intLike :: Parser Integer intLike = Parser Integer parser Parser Integer -> Parser Integer -> Parser Integer forall a. Parser a -> Parser a -> Parser a <|> Parser Integer int where parser :: Parser Integer parser = do String n1 <- Integer -> String forall a. Show a => a -> String show (Integer -> String) -> Parser Integer -> Parser String forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parser Integer int String n2 <- Integer -> String forall a. Show a => a -> String show (Integer -> String) -> Parser Integer -> Parser String forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (Parser Char dot Parser Char -> Parser Integer -> Parser Integer forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser Integer unsignedInt) Integer expNum <- String -> Parser Char forall a. IsMatch a => [a] -> Parser a oneOf [Char 'e', Char 'E'] Parser Char -> Parser Integer -> Parser Integer forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser Integer int if String -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length String n1 Int -> Int -> Int forall a. Num a => a -> a -> a + String -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length String n2 Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <= Integer -> Int forall a. Num a => Integer -> a fromInteger Integer expNum then Integer -> Parser Integer forall (f :: * -> *) a. Applicative f => a -> f a pure (Integer -> Parser Integer) -> (String -> Integer) -> String -> Parser Integer forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> Integer forall a. Read a => String -> a read (String -> Parser Integer) -> String -> Parser Integer forall a b. (a -> b) -> a -> b $ String n1 String -> String -> String forall a. [a] -> [a] -> [a] ++ String "." String -> String -> String forall a. [a] -> [a] -> [a] ++ String n2 String -> String -> String forall a. [a] -> [a] -> [a] ++ String "E" String -> String -> String forall a. [a] -> [a] -> [a] ++ Integer -> String forall a. Show a => a -> String show Integer expNum else ParseError -> Parser Integer forall a. ParseError -> Parser a errorParser (ParseError -> Parser Integer) -> ParseError -> Parser Integer forall a b. (a -> b) -> a -> b $ String -> ParseError NoMatch String "intLike" double :: Parser Double double :: Parser Double double = String -> Double forall a. Read a => String -> a read (String -> Double) -> Parser String -> Parser Double forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parser Integer int Parser Integer -> Parser (Maybe String) -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> (Parser String decimals Parser String -> Parser (Maybe String) forall a. Parser a -> Parser (Maybe a) |?) Parser String -> Parser (Maybe String) -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> (Parser String expn Parser String -> Parser (Maybe String) forall a. Parser a -> Parser (Maybe a) |?) where decimals :: Parser String decimals = Parser Char dot Parser Char -> Parser Integer -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> Parser Integer unsignedInt expn :: Parser String expn = String -> Parser Char forall a. IsMatch a => [a] -> Parser a oneOf [Char 'e', Char 'E'] Parser Char -> Parser Integer -> Parser String forall a b. (ToString a, ToString b) => Parser a -> Parser b -> Parser String >>> Parser Integer int