module Hasmin.Parser.Numeric
( alphavalue
, rational
, int
, percentage
, number
) where
import Control.Applicative ((<|>))
import Numeric (readSigned, readFloat)
import Data.Attoparsec.Text (Parser)
import qualified Data.Attoparsec.Text as A
import Hasmin.Types.Numeric
import Hasmin.Parser.Utils
import Hasmin.Parser.Primitives
number :: Parser Number
number = Number <$> rational
percentage :: Parser Percentage
percentage = Percentage <$> rational <* A.char '%'
alphavalue :: Parser Alphavalue
alphavalue = mkAlphavalue <$> rational
rational :: Parser Rational
rational = do
sign <- A.option [] (wrapMinus <$> (A.char '-' <|> A.char '+'))
dgts <- ((++) <$> digits <*> A.option "" fractionalPart)
<|> ("0"++) <$> fractionalPart
e <- A.option [] expo
pure . fst . head $ readSigned readFloat (sign ++ dgts ++ e)
where fractionalPart = (:) <$> A.char '.' <*> digits
expo = (:) <$> A.satisfy (\c -> c == 'e' || c == 'E') <*> int'
wrapMinus x = [x | x == '-']