itos.ha (2609B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use strings; 5 use types; 6 7 // Converts an i64 to a string. The return value is statically allocated and 8 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate 9 // the result. 10 export fn i64tos(i: i64, b: base = base::DEC) const str = { 11 static assert(types::I64_MAX == 9223372036854775807); 12 if (b == base::DEFAULT) { 13 b = base::DEC; 14 }; 15 16 if (i >= 0) return u64tos(i: u64, b); 17 18 static let buf: [65]u8 = [0...]; // 64 binary digits plus - 19 20 let s = types::string { data = &buf, ... }; 21 22 buf[0] = '-'; 23 s.length = 1; 24 25 let u = strings::toutf8(u64tos((-i): u64, b)); 26 assert(len(u) < len(buf)); 27 28 buf[1..len(u) + 1] = u[..]; 29 s.length += len(u); 30 31 return *(&s: *str); 32 }; 33 34 // Converts an i32 to a string. The return value is statically allocated and 35 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate 36 // the result. 37 export fn i32tos(i: i32, b: base = base::DEC) const str = i64tos(i, b); 38 39 // Converts an i16 to a string. The return value is statically allocated and 40 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate 41 // the result. 42 export fn i16tos(i: i16, b: base = base::DEC) const str = i64tos(i, b); 43 44 // Converts an i8 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 i8tos(i: i8, b: base = base::DEC) const str = i64tos(i, b); 48 49 // Converts an int to a string. The return value is statically allocated and 50 // will be overwritten on subsequent calls; see [[strings::dup]] to duplicate 51 // the result. 52 export fn itos(i: int, b: base = base::DEC) const str = i64tos(i, b); 53 54 @test fn itos_bases() void = { 55 assert("11010" == i64tos(0b11010, base::BIN)); 56 assert("1234567" == i64tos(0o1234567, base::OCT)); 57 assert("123456789" == i64tos(123456789, base::DEC)); 58 assert("123456789ABCDEF" == i64tos(0x123456789ABCDEF, base::HEX)); 59 assert("123456789ABCDEF" == i64tos(0x123456789ABCDEF, base::HEX_UPPER)); 60 assert("123456789abcdef" == i64tos(0x123456789ABCDEF, base::HEX_LOWER)); 61 assert("-1000000000000000000000000000000000000000000000000000000000000000" 62 == i64tos(types::I64_MIN, base::BIN)); 63 }; 64 65 @test fn itos() void = { 66 const samples: [_]i64 = [ 67 1234, 68 4321, 69 -1337, 70 0, 71 types::I64_MAX, 72 types::I64_MIN, 73 ]; 74 const expected = [ 75 "1234", 76 "4321", 77 "-1337", 78 "0", 79 "9223372036854775807", 80 "-9223372036854775808", 81 ]; 82 83 for (let i = 0z; i < len(samples); i += 1) { 84 const s = i64tos(samples[i]); 85 assert(s == expected[i]); 86 }; 87 };