Add a few more parsers for numbers

This commit is contained in:
Joscha 2019-11-20 17:16:00 +00:00
parent f8c5d2766c
commit 602e8b5b14

View file

@ -9,9 +9,15 @@ module Mima.Parse.Common
-- ** Number literals -- ** Number literals
, binDigit , binDigit
, decDigit , decDigit
, octDigit
, hexDigit , hexDigit
, binNumber
, decNumber
, octNumber
, hexNumber
, fixedWidthBin , fixedWidthBin
, fixedWidthDec , fixedWidthDec
, fixedWidthOct
, fixedWidthHex , fixedWidthHex
-- ** MiMa types -- ** MiMa types
, asWord , asWord
@ -59,6 +65,19 @@ binDigit = label "binary digit" $ token helper Set.empty
helper '1' = Just 1 helper '1' = Just 1
helper _ = Nothing helper _ = Nothing
octDigit :: (Num a) => Parser a
octDigit = label "octal digit" $ token helper Set.empty
where
helper '0' = Just 0
helper '1' = Just 1
helper '2' = Just 2
helper '3' = Just 3
helper '4' = Just 4
helper '5' = Just 5
helper '6' = Just 6
helper '7' = Just 7
helper _ = Nothing
decDigit :: (Num a) => Parser a decDigit :: (Num a) => Parser a
decDigit = label "decimal digit" $ token helper Set.empty decDigit = label "decimal digit" $ token helper Set.empty
where where
@ -95,6 +114,25 @@ hexDigit = label "hexadecimal digit" $ token (helper . toLower) Set.empty
helper 'f' = Just 15 helper 'f' = Just 15
helper _ = Nothing helper _ = Nothing
accumulateToBase :: (Integral a) => a -> [a] -> a
accumulateToBase base = helper
where
helper [] = 0
helper [d] = d
helper (d:ds) = d + base * helper ds
binNumber :: (Integral a) => Parser a
binNumber = label "binary number" $ accumulateToBase 2 <$> some binDigit
octNumber :: (Integral a) => Parser a
octNumber = label "octal number" $ accumulateToBase 8 <$> some octDigit
decNumber :: (Integral a) => Parser a
decNumber = label "decimal number" $ accumulateToBase 10 <$> some decDigit
hexNumber :: (Integral a) => Parser a
hexNumber = label "hexadecimal number" $ accumulateToBase 16 <$> some hexDigit
fixedWidthWithExponent :: (Num a) => a -> Parser a -> Int -> Parser a fixedWidthWithExponent :: (Num a) => a -> Parser a -> Int -> Parser a
fixedWidthWithExponent e digit width = do fixedWidthWithExponent e digit width = do
digits <- count width digit digits <- count width digit
@ -106,6 +144,9 @@ fixedWidthWithExponent e digit width = do
fixedWidthBin :: (Num a) => Int -> Parser a fixedWidthBin :: (Num a) => Int -> Parser a
fixedWidthBin = fixedWidthWithExponent 2 binDigit fixedWidthBin = fixedWidthWithExponent 2 binDigit
fixedWidthOct :: (Num a) => Int -> Parser a
fixedWidthOct = fixedWidthWithExponent 8 octDigit
fixedWidthDec :: (Num a) => Int -> Parser a fixedWidthDec :: (Num a) => Int -> Parser a
fixedWidthDec = fixedWidthWithExponent 10 decDigit fixedWidthDec = fixedWidthWithExponent 10 decDigit