hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

utos.ha (3369B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bytes;
      5 use types;
      6 
      7 // Converts a u64 to a string. The return value is statically allocated and will
      8 // be overwritten on subsequent calls; see [[strings::dup]] to duplicate the
      9 // result.
     10 export fn u64tos(u: u64, b: base = base::DEC) const str = {
     11 	static assert(types::U64_MAX == 18446744073709551615);
     12 	static let buf: [64]u8 = [0...]; // 64 binary digits
     13 
     14 	static const lut_upper = [
     15 		'0', '1', '2', '3', '4', '5', '6', '7',
     16 		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
     17 	], lut_lower = [
     18 		'0', '1', '2', '3', '4', '5', '6', '7',
     19 		'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
     20 	];
     21 	const lut = if (b != base::HEX_LOWER) &lut_upper else {
     22 		b = base::HEX_UPPER;
     23 		yield &lut_lower;
     24 	};
     25 
     26 	const b: uint = if (b == base::DEFAULT) base::DEC else b;
     27 
     28 	let s = types::string { data = &buf, ... };
     29 	if (u == 0) {
     30 		buf[s.length] = '0';
     31 		s.length += 1z;
     32 	};
     33 
     34 	for (u > 0u64) {
     35 		buf[s.length] = lut[u % b: u64]: u8;
     36 		s.length += 1;
     37 		u /= b;
     38 	};
     39 
     40 	bytes::reverse(buf[..s.length]);
     41 	return *(&s: *str);
     42 };
     43 
     44 // Converts a u32 to a string. The return value is statically allocated and will
     45 // be overwritten on subsequent calls; see [[strings::dup]] to duplicate the
     46 // result.
     47 export fn u32tos(u: u32, b: base = base::DEC) const str = u64tos(u, b);
     48 
     49 // Converts a u16 to a string. The return value is statically allocated and will
     50 // be overwritten on subsequent calls; see [[strings::dup]] to duplicate the
     51 // result.
     52 export fn u16tos(u: u16, b: base = base::DEC) const str = u64tos(u, b);
     53 
     54 // Converts a u8 to a string. The return value is statically allocated and will
     55 // be overwritten on subsequent calls; see [[strings::dup]] to duplicate the
     56 // result.
     57 export fn u8tos(u: u8, b: base = base::DEC) const str = u64tos(u, b);
     58 
     59 // Converts a uint to a string. The return value is statically allocated and
     60 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate
     61 // the result.
     62 export fn utos(u: uint, b: base = base::DEC) const str = u64tos(u, b);
     63 
     64 // Converts a size to a string. The return value is statically allocated and
     65 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate
     66 // the result.
     67 export fn ztos(u: size, b: base = base::DEC) const str = u64tos(u, b);
     68 
     69 // Converts a uintptr to a string. The return value is statically allocated and
     70 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate
     71 // the result.
     72 export fn uptrtos(uptr: uintptr, b: base = base::DEC) const str = u64tos(uptr: u64, b);
     73 
     74 @test fn utos_bases() void = {
     75 	assert("11010" == u64tos(0b11010, base::BIN));
     76 	assert("1234567" == u64tos(0o1234567, base::OCT));
     77 	assert("123456789" == u64tos(123456789, base::DEC));
     78 	assert("123456789ABCDEF" == u64tos(0x123456789ABCDEF, base::HEX));
     79 	assert("123456789ABCDEF" == u64tos(0x123456789ABCDEF, base::HEX_UPPER));
     80 	assert("123456789abcdef" == u64tos(0x123456789ABCDEF, base::HEX_LOWER));
     81 	assert("1111111111111111111111111111111111111111111111111111111111111111"
     82 		== u64tos(types::U64_MAX, base::BIN));
     83 };
     84 
     85 @test fn utos() void = {
     86 	const samples: [_]u64 = [
     87 		1234,
     88 		4321,
     89 		types::U64_MIN,
     90 		types::U64_MAX,
     91 	];
     92 	const expected = [
     93 		"1234",
     94 		"4321",
     95 		"0",
     96 		"18446744073709551615",
     97 	];
     98 
     99 	for (let i = 0z; i < len(samples); i += 1) {
    100 		const s = u64tos(samples[i]);
    101 		assert(s == expected[i]);
    102 	};
    103 };