From 48510fb45403de8920448f9b73ceb8ca7c23d160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20Gr=C3=B6nlund?= Date: Tue, 23 May 2017 22:46:16 +0200 Subject: [PATCH] Customize format for I32/U32 (#1920) Fixes formatting of I32.min_value(). TODO: the u32 and u64 funs in _format_int.pony could probably be largely re-unified. Update formatting to follow style guide proposal (#1894). Fixes: #1920 --- packages/format/_format_int.pony | 70 ++++++++++++++++++++++++++++---- packages/format/_test.pony | 2 + packages/format/format.pony | 4 +- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/packages/format/_format_int.pony b/packages/format/_format_int.pony index 0b2fc2aeaae..ce75066854b 100644 --- a/packages/format/_format_int.pony +++ b/packages/format/_format_int.pony @@ -65,9 +65,59 @@ primitive _FormatInt s.reverse_in_place() end - fun u64(x: U64, neg: Bool, fmt: FormatInt, prefix: PrefixNumber, - prec: USize, width: USize, align: Align, fill: U32 - ): String iso^ => + fun u32( + x: U32, + neg: Bool, + fmt: FormatInt, + prefix: PrefixNumber, + prec: USize, + width: USize, + align: Align, + fill: U32) + : String iso^ + => + match fmt + | FormatUTF32 => return recover String.from_utf32(x.u32()) end + end + + (var base', var typestring, var table) = _fmt_int(fmt) + var prestring = _prefix(neg, prefix) + var prec' = if prec == -1 then 0 else prec end + let base = base'.u32() + + recover + var s = String((prec + 1).max(width.max(31))) + var value = x + + try + if value == 0 then + s.push(table(0)) + else + while value != 0 do + let index = ((value = value / base) - (value * base)) + s.push(table(index.usize())) + end + end + end + + _extend_digits(s, prec') + s.append(typestring) + s.append(prestring) + _pad(s, width, align, fill) + s + end + + fun u64( + x: U64, + neg: Bool, + fmt: FormatInt, + prefix: PrefixNumber, + prec: USize, + width: USize, + align: Align, + fill: U32) + : String iso^ + => match fmt | FormatUTF32 => return recover String.from_utf32(x.u32()) end end @@ -99,10 +149,16 @@ primitive _FormatInt s end - fun u128(x: U128, neg: Bool, fmt: FormatInt = FormatDefault, - prefix: PrefixNumber = PrefixDefault, prec: USize = -1, width: USize = 0, - align: Align = AlignLeft, fill: U32 = ' ' - ): String iso^ => + fun u128(x: U128, + neg: Bool, + fmt: FormatInt = FormatDefault, + prefix: PrefixNumber = PrefixDefault, + prec: USize = -1, + width: USize = 0, + align: Align = AlignLeft, + fill: U32 = ' ') + : String iso^ + => match fmt | FormatUTF32 => return recover String.from_utf32(x.u32()) end end diff --git a/packages/format/_test.pony b/packages/format/_test.pony index 9f5f47b7f19..9a6bf24310d 100644 --- a/packages/format/_test.pony +++ b/packages/format/_test.pony @@ -24,6 +24,8 @@ class iso _TestInt is UnitTest fun name(): String => "format/int" fun apply(h: TestHelper) => + h.assert_eq[String]("-2147483648", + Format.int[I32](I32.min_value())) h.assert_eq[String]("00010", Format.int[U64](10, FormatDefault, PrefixDefault, 5)) h.assert_eq[String]("0x0000A", diff --git a/packages/format/format.pony b/packages/format/format.pony index f56aad56708..23868777e07 100644 --- a/packages/format/format.pony +++ b/packages/format/format.pony @@ -96,8 +96,10 @@ primitive Format _FormatInt.u128(x.u128(), false, fmt, prefix, prec, width, align, fill) elseif x is I128 then _FormatInt.u128(abs.u128(), neg, fmt, prefix, prec, width, align, fill) - else + elseif (x is U64) or (x is I64) then _FormatInt.u64(abs.u64(), neg, fmt, prefix, prec, width, align, fill) + else + _FormatInt.u32(abs.u32(), neg, fmt, prefix, prec, width, align, fill) end fun float[A: (Float & FloatingPoint[A])](x: A,