## number-format.pkg
# Compiled by:
#
src/lib/std/src/standard-core.sublib# The word to string conversion for the largest word and int types.
# All of the other fmt functions can be implemented in terms of them.
### "War does not determine who is right - only who is left."
###
### -- Bertrand Russell
stipulate
package i32 = inline_t::i1; # "i1" == one-word signed int (32-bits on 32-bit architectures; 64-bits on 64-bit architectures.)
package u32 = inline_t::u1; # "u1" == one-word unsigned int (32-bits on 32-bit architectures; 64-bits on 64-bit architectures.)
#
package i1w = one_word_int; # one_word_int is from
src/lib/std/types-only/basis-structs.pkg package u1w = one_word_unt; # one_word_unt is from
src/lib/std/types-only/basis-structs.pkg #
package it = inline_t; # inline_t is from
src/lib/core/init/built-in.pkg package ns = number_string; # number_string is from
src/lib/std/src/number-string.pkg package ps = protostring; # protostring is from
src/lib/std/src/protostring.pkg package ti = inline_t::ti; # "ti" == "tagged_int". (31-bits on 32-bit architectures; 63-bits on 64-bit architectures.)
herein
package number_format: (weak) api {
#
format_unt: ns::Radix -> u1w::Unt -> String;
format_int: ns::Radix -> i1w::Int -> String;
}
{
(<) = u32::(<);
(-) = u32::(-);
(*) = u32::(*);
(div) = u32::div;
fun make_digit (w: u1w::Unt)
=
it::vector_of_chars::get_byte_as_char ("0123456789ABCDEF", u32::to_int w);
fun word_to_bin w
=
f (w, 0, [])
where
fun make_bit w
=
u32::bitwise_and (w, 0u1) == 0u0
?? '0'
:: '1';
fun f (0u0, n, l) => (ti::(+) (n, 1), '0' ! l);
f (0u1, n, l) => (ti::(+) (n, 1), '1' ! l);
f (w, n, l) => f (u32::rshiftl (w, 0u1), ti::(+) (n, 1), (make_bit w) ! l);
end;
end;
fun word_to_oct w
=
f (w, 0, [])
where
fun f (w, n, l)
=
if (w < 0u8) (ti::(+) (n, 1), (make_digit w) ! l);
else f (u32::rshiftl (w, 0u3), ti::(+) (n, 1), make_digit (u32::bitwise_and (w, 0ux7)) ! l);
fi;
end;
fun word_to_dec w
=
f (w, 0, [])
where
fun f (w, n, l)
=
if (w < 0u10)
#
(ti::(+) (n, 1), (make_digit w) ! l);
else
j = w div 0u10;
#
f (j, ti::(+) (n, 1), make_digit (w - 0u10*j) ! l);
fi;
end;
fun word_to_hex w
=
f (w, 0, [])
where
fun f (w, n, l)
=
if (w < 0u16) (ti::(+) (n, 1), (make_digit w) ! l);
else f (u32::rshiftl (w, 0u4), ti::(+) (n, 1), make_digit (u32::bitwise_and (w, 0uxf)) ! l);
fi;
end;
fun format_w ns::BINARY => word_to_bin;
format_w ns::OCTAL => word_to_oct;
format_w ns::DECIMAL => word_to_dec;
format_w ns::HEX => word_to_hex;
end;
fun format_unt radix
=
ps::implode o (format_w radix);
i2w = u32::from_large_int o i32::to_large;
fun format_int radix i
=
if (i2w i == 0ux80000000)
#
"-2147483648";
else
w32 = i2w (if (i32::(<) (i, 0) ) i32::neg(i); else i;fi);
(format_w radix w32)
->
(n, digits);
if (i32::(<) (i, 0)) ps::implode (ti::(+) (n, 1), '-' ! digits);
else ps::implode (n, digits);
fi;
fi;
};
end;