From 0c3193659002fd6d01350d54a260823b65ce8678 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 10 Dec 2020 14:52:43 -0700 Subject: [PATCH] maintain explicit padding in unsized number literals --- src/Language/SystemVerilog/AST/Number.hs | 18 +++++++++++------- test/lex/number.sv | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/Language/SystemVerilog/AST/Number.hs b/src/Language/SystemVerilog/AST/Number.hs index e1941e8..c25f01b 100644 --- a/src/Language/SystemVerilog/AST/Number.hs +++ b/src/Language/SystemVerilog/AST/Number.hs @@ -78,7 +78,7 @@ parseNumber' str = if rawSize /= 0 then rawSize else if maybeBase /= Nothing then - negate $ max 32 (bitsPerDigit * numDigits) + negate $ bitsPerDigit * numDigits else -32 bitsPerDigit = bits $ baseSize base - 1 @@ -170,7 +170,11 @@ baseSize Hex = 16 numberBitLength :: Number -> Integer numberBitLength UnbasedUnsized{} = 32 numberBitLength (Decimal size _ _) = fromIntegral $ abs size -numberBitLength (Based size _ _ _ _) = fromIntegral $ abs size +numberBitLength (Based size _ _ _ _) = + fromIntegral $ + if size < 0 + then max 32 $ negate size + else size -- get whether or not a number is signed numberIsSized :: Number -> Bool @@ -226,16 +230,16 @@ instance Show Number where sizeStr = if size > 0 then show size else "" signedStr = if signed then "s" else "" [baseCh] = show base - valueStr = showBasedDigits (baseSize base) size value kinds + valueStr = showBasedDigits signed (baseSize base) size value kinds -showBasedDigits :: Int -> Int -> Integer -> Integer -> String -showBasedDigits base size values kinds = +showBasedDigits :: Bool -> Int -> Int -> Integer -> Integer -> String +showBasedDigits signed base size values kinds = if numDigits > sizeDigits then error $ "invalid based literal digits: " ++ show (base, size, values, kinds, numDigits, sizeDigits) - else if size < -32 then + else if size < -32 || (size < 0 && signed) then padList '0' sizeDigits digits - else if leadingXZ && size < 0 then + else if leadingXZ && size < 0 && sizeDigits == numDigits then removeExtraPadding digits else if leadingXZ || (256 >= size && size > 0) then padList '0' sizeDigits digits diff --git a/test/lex/number.sv b/test/lex/number.sv index fb8a3a8..6b900a4 100644 --- a/test/lex/number.sv +++ b/test/lex/number.sv @@ -37,5 +37,19 @@ module top; `TEST('h01xz01xz) `TEST('h101xz01xz) `TEST(36'h01xz01xz) `TEST(37'h01xz01xz) `TEST(36'hb01xz01xz) `TEST(37'hb01xz01xz) + + `TEST('sb0) `TEST('sb1) + `TEST('sb00) `TEST('sb10) `TEST('sb01) `TEST('sb11) + `TEST('sb000) `TEST('sb001) `TEST('sb010) `TEST('sb011) + `TEST('sb100) `TEST('sb101) `TEST('sb110) `TEST('sb111) + + `TEST('b0) `TEST('b1) + `TEST('b00) `TEST('b10) `TEST('b01) `TEST('b11) + `TEST('b000) `TEST('b001) `TEST('b010) `TEST('b011) + `TEST('b100) `TEST('b101) `TEST('b110) `TEST('b111) + + `TEST('b0x) `TEST('sb0x) `TEST('b0z) `TEST('sb0z) + `TEST('o0x) `TEST('so0x) `TEST('o0z) `TEST('so0z) + `TEST('h0x) `TEST('sh0x) `TEST('h0z) `TEST('sh0z) end endmodule