Skip to content

Commit d4639b7

Browse files
author
Leonidas Loucas
committed
Add handling for HexFloatLiterals #455
1 parent 84a4930 commit d4639b7

File tree

2 files changed

+44
-10
lines changed

2 files changed

+44
-10
lines changed

src/Language/Haskell/Exts/Extension.hs

+3
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,9 @@ data KnownExtension =
560560

561561
| BlockArguments
562562

563+
-- | HexFloatLiterals syntax ex 0xFF.FFp-12
564+
| HexFloatLiterals
565+
563566
deriving (Show, Read, Eq, Ord, Enum, Bounded, Data, Typeable)
564567

565568
-- | Certain extensions imply other extensions, and this function

src/Language/Haskell/Exts/InternalLexer.hs

+41-10
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,9 @@ lexStdToken = do
668668
(n, str) <- lexBinary
669669
con <- intHash
670670
return (con (n, '0':c:str))
671+
| toLower c == 'x' && isHexDigit d && HexFloatLiterals `elem` exts -> do
672+
discard 2
673+
lexHexadecimalFloat c
671674
| toLower c == 'x' && isHexDigit d -> do
672675
discard 2
673676
(n, str) <- lexHexadecimal
@@ -1036,22 +1039,50 @@ lexDecimalOrFloat = do
10361039
'#':_ | MagicHash `elem` exts -> discard 1 >> return (IntTokHash (parseInteger 10 ds, ds))
10371040
_ -> return (IntTok (parseInteger 10 ds, ds))
10381041

1039-
where
1040-
lexExponent :: Lex a (Integer, String)
1041-
lexExponent = do
1042-
(e:r) <- getInput
1043-
discard 1 -- 'e' or 'E'
1044-
case r of
1045-
'+':d:_ | isDigit d -> do
1042+
lexExponent :: Lex a (Integer, String)
1043+
lexExponent = do
1044+
(e:r) <- getInput
1045+
discard 1 -- discard ex notation
1046+
case r of
1047+
'+':d:_ | isDigit d -> do
10461048
discard 1
10471049
(n, str) <- lexDecimal
10481050
return (n, e:'+':str)
1049-
'-':d:_ | isDigit d -> do
1051+
'-':d:_ | isDigit d -> do
10501052
discard 1
10511053
(n, str) <- lexDecimal
10521054
return (negate n, e:'-':str)
1053-
d:_ | isDigit d -> lexDecimal >>= \(n,str) -> return (n, e:str)
1054-
_ -> fail "Float with missing exponent"
1055+
d:_ | isDigit d -> lexDecimal >>= \(n,str) -> return (n, e:str)
1056+
_ -> fail "Float with missing exponent"
1057+
1058+
lexHexadecimalFloat :: Char -> Lex a Token
1059+
lexHexadecimalFloat c = do
1060+
ds <- lexWhile isHexDigit
1061+
rest <- getInput
1062+
exts <- getExtensionsL
1063+
case rest of
1064+
('.':d:_) | isHexDigit d -> do
1065+
discard 1
1066+
frac <- lexWhile isHexDigit
1067+
let num = parseInteger 16 ds
1068+
numFrac = parseFrac frac
1069+
(exponent, estr) <- do
1070+
rest2 <- getInput
1071+
case rest2 of
1072+
'p':_ -> lexExponent
1073+
'P':_ -> lexExponent
1074+
_ -> return (0,"")
1075+
con <- lexHash FloatTok FloatTokHash (Right DoubleTokHash)
1076+
return $ con (((num%1) + numFrac) * 2^^(exponent), '0':c:ds ++ '.':frac ++ estr)
1077+
e:_ | toLower e == 'p' -> do
1078+
(exponent, estr) <- lexExponent
1079+
con <- lexHash FloatTok FloatTokHash (Right DoubleTokHash)
1080+
return $ con (((parseInteger 16 ds)%1) * 2^^exponent, '0':c:ds ++ estr)
1081+
_ -> return (IntTok (parseInteger 16 ds, '0':c:ds))
1082+
where
1083+
parseFrac :: String -> Rational
1084+
parseFrac ds =
1085+
foldl (\n (dp, d) -> n + (d / (16 ^^ dp))) (0 % 1) $ zip [1..] (map ((% 1) . toInteger . digitToInt) ds)
10551086

10561087
lexHash :: (b -> Token) -> (b -> Token) -> Either String (b -> Token) -> Lex a (b -> Token)
10571088
lexHash a b c = do

0 commit comments

Comments
 (0)