Skip to content

Commit

Permalink
Customize format for all Number types (#1920)
Browse files Browse the repository at this point in the history
Fixes formatting of I32.min_value(), I16.min_value(),
etc.

TODO: the various type-specific  funs in
_format_int.pony could probably be
largely re-unified.

Update formatting to follow style
guide proposal (#1894).

Fixes: #1920
  • Loading branch information
krig committed May 31, 2017
1 parent ee8b506 commit 53dfce8
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 10 deletions.
147 changes: 140 additions & 7 deletions packages/format/_format_int.pony
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,135 @@ 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 u8(
x: U8,
neg: Bool,
fmt: FormatInt,
prefix: PrefixNumber,
prec: USize,
width: USize,
align: Align,
fill: U32)
: String iso^
=>
(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'.u8()

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 u16(
x: U16,
neg: Bool,
fmt: FormatInt,
prefix: PrefixNumber,
prec: USize,
width: USize,
align: Align,
fill: U32)
: String iso^
=>
(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'.u16()

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 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
Expand Down Expand Up @@ -99,10 +225,17 @@ 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
Expand Down
17 changes: 17 additions & 0 deletions packages/format/_test.pony
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ class iso _TestInt is UnitTest
fun name(): String => "format/int"

fun apply(h: TestHelper) =>
ifdef ilp32 or llp64 then
h.assert_eq[String]("-2147483648",
Format.int[ISize](ISize.min_value()))
else
h.assert_eq[String]("-9223372036854775808",
Format.int[ISize](ISize.min_value()))
end
h.assert_eq[String]("-9223372036854775808",
Format.int[I64](I64.min_value()))
h.assert_eq[String]("0",
Format.int[U32](U32.min_value()))
h.assert_eq[String]("-2147483648",
Format.int[I32](I32.min_value()))
h.assert_eq[String]("-32768",
Format.int[I16](I16.min_value()))
h.assert_eq[String]("-128",
Format.int[I8](I8.min_value()))
h.assert_eq[String]("00010",
Format.int[U64](10, FormatDefault, PrefixDefault, 5))
h.assert_eq[String]("0x0000A",
Expand Down
20 changes: 17 additions & 3 deletions packages/format/format.pony
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,26 @@ primitive Format
let zero = x.from[USize](0)
(let abs, let neg) = if x < zero then (-x, true) else (x, false) end

if x is U128 then
iftype A <: U128 then
_FormatInt.u128(x.u128(), false, fmt, prefix, prec, width, align, fill)
elseif x is I128 then
elseif A <: I128 then
_FormatInt.u128(abs.u128(), neg, fmt, prefix, prec, width, align, fill)
else
elseif A <: (U64 | I64) then
_FormatInt.u64(abs.u64(), neg, fmt, prefix, prec, width, align, fill)
elseif A <: (U32 | I32) then
_FormatInt.u32(abs.u32(), neg, fmt, prefix, prec, width, align, fill)
elseif A <: (U16 | I16) then
_FormatInt.u16(abs.u16(), neg, fmt, prefix, prec, width, align, fill)
elseif A <: (U8 | I8) then
_FormatInt.u8(abs.u8(), neg, fmt, prefix, prec, width, align, fill)
elseif A <: (USize | ISize | ULong | ILong) then
ifdef ilp32 or llp64 then
_FormatInt.u32(abs.u32(), neg, fmt, prefix, prec, width, align, fill)
else
_FormatInt.u64(abs.u64(), neg, fmt, prefix, prec, width, align, fill)
end
else
_FormatInt.u128(x.u128(), false, fmt, prefix, prec, width, align, fill)
end

fun float[A: (Float & FloatingPoint[A])](x: A,
Expand Down

0 comments on commit 53dfce8

Please sign in to comment.