Add parsing for binary and octal fractional literals.

I doubt these are super common but we add them for completeness,
and because with the floats we can print in those bases
This commit is contained in:
Iavor Diatchki 2020-07-14 11:31:54 -07:00
parent 173a04fc01
commit 42b2ac6b45
6 changed files with 47 additions and 7 deletions

View File

@ -285,7 +285,9 @@ data NumInfo = BinLit Int -- ^ n-digit binary literal
deriving (Eq, Show, Generic, NFData)
-- | Information about fractional literals.
data FracInfo = DecFrac
data FracInfo = BinFrac
| OctFrac
| DecFrac
| HexFrac
deriving (Eq,Show,Generic,NFData)
@ -644,13 +646,15 @@ ppFracLit :: Rational -> FracInfo -> Doc
ppFracLit x i
| toRational dbl == x =
case i of
BinFrac -> frac
OctFrac -> frac
DecFrac -> text (showFloat dbl "")
HexFrac -> text (showHFloat dbl "")
| otherwise =
"fraction`" <.> braces
(commaSep (map integer [ numerator x, denominator x ]))
| otherwise = frac
where
dbl = fromRational x :: Double
frac = "fraction`" <.> braces
(commaSep (map integer [ numerator x, denominator x ]))
ppNumLit :: Integer -> NumInfo -> Doc

View File

@ -45,11 +45,15 @@ $unitick = \x7
@qual_id = @qual @id
@qual_op = @qual @op
@num2 = "0b" (_*[0-1])+
@num8 = "0o" (_*[0-7])+
@num10 = [0-9](_*[0-9])*
@digits2 = (_*[0-1])+
@digits8 = (_*[0-7])+
@digits16 = (_*[0-9A-Fa-f])+
@num2 = "0b" @digits2
@num8 = "0o" @digits8
@num10 = [0-9](_*[0-9])*
@num16 = "0x" @digits16
@fnum2 = @num2 "." @digits2 ([pP] [\+\-]? @num10)?
@fnum8 = @num8 "." @digits8 ([pP] [\+\-]? @num10)?
@fnum10 = @num10 "." @num10 ([eE] [\+\-]? @num10)?
@fnum16 = @num16 "." @digits16 ([pP] [\+\-]? @num10)?
@ -130,6 +134,8 @@ $white+ { emit $ White Space }
@num8 { emitS (numToken 8 . Text.drop 2) }
@num10 { emitS (numToken 10 . Text.drop 0) }
@num16 { emitS (numToken 16 . Text.drop 2) }
@fnum2 { emitS (fnumToken 2 . Text.drop 2) }
@fnum8 { emitS (fnumToken 8 . Text.drop 2) }
@fnum10 { emitS (fnumToken 10 . Text.drop 0) }
@fnum16 { emitS (fnumToken 16 . Text.drop 2) }

View File

@ -214,6 +214,8 @@ fracLit :: TokenT -> Expr PName
fracLit tok =
case tok of
Frac x base
| base == 2 -> ELit $ ECFrac x BinFrac
| base == 8 -> ELit $ ECFrac x OctFrac
| base == 10 -> ELit $ ECFrac x DecFrac
| base == 16 -> ELit $ ECFrac x HexFrac
_ -> panic "[Parser] fracLit" [ "Invalid fraction", show tok ]

View File

@ -127,6 +127,8 @@ desugarLiteral lit =
let arg f = P.PosInst (P.TNum (f fr))
rnd = P.PosInst (P.TNum (case info of
P.DecFrac -> 0
P.BinFrac -> 1
P.OctFrac -> 1
P.HexFrac -> 1))
in P.EAppT fracPrim [ arg numerator, arg denominator, rnd ]

View File

@ -0,0 +1,13 @@
0b1.1 : Rational
0o1.1 : Rational
1.1 : Rational
0x1.1 : Rational
0b1.1p3 : Rational
0o1.1p3 : Rational
1.1e3 : Rational
0x1.1p3 : Rational
0b1.1p-3 : Rational
0o1.1p-3 : Rational
1.1e-3 : Rational
0x1.1p-3 : Rational

View File

@ -0,0 +1,13 @@
Loading module Cryptol
(ratio 3 2)
(ratio 9 8)
(ratio 11 10)
(ratio 17 16)
(ratio 12 1)
(ratio 9 1)
(ratio 1100 1)
(ratio 17 2)
(ratio 3 16)
(ratio 9 64)
(ratio 11 10000)
(ratio 17 128)