hare

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

commit 95feeffe79767bb2b7a59948d8acffdfc18d9eb5
parent bdec75d3f4712d6db9ce28ecbd35e483d8b9f3e1
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 24 Jan 2021 13:16:56 -0500

strconv: new module

Diffstat:
Abytes/reverse.ha | 10++++++++++
Astrconv/itos.ha | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astrconv/numeric.ha | 45+++++++++++++++++++++++++++++++++++++++++++++
Astrconv/utos.ha | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 260 insertions(+), 0 deletions(-)

diff --git a/bytes/reverse.ha b/bytes/reverse.ha @@ -0,0 +1,10 @@ +// Reverses a slice of bytes. +export fn reverse(b: []u8) void = { + for (let s = 0z, e = len(b) - 1z; s < e) { + let x = b[s]; + b[s] = b[e]; + b[e] = x; + s += 1z; + e -= 1z; + }; +}; diff --git a/strconv/itos.ha b/strconv/itos.ha @@ -0,0 +1,94 @@ +use bytes; +use types; + +// Converts an i64 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::i64tos(1234); +// io::printf("%s", a); // 1234 +// +// let a = strconv::i64tos(1234); +// let b = strconv::i64tos(4321); +// io::printf("%s %s", a, b); // 4321 4321 +export fn i64tos(i: i64) const str = { + static assert(types::I64_MAX == 9223372036854775807i64); + static let buf: [22]u8 = [0u8...]; // 20 chars plus NUL and - + buf = [0u8...]; + + let s = struct { + b: *[*]u8 = &buf, + l: size = 0z, + c: size = 0z, + }; + + const isneg = i < 0i64; + if (isneg) { + s.b[s.l] = '-': u32: u8; + s.l += 1z; + i = -i; + } else if (i == 0i64) { + s.b[s.l] = '0': u32: u8; + s.l += 1z; + }; + + for (i > 0i64) { + s.b[s.l] = '0': u32: u8 + (i % 10i64): u8; + s.l += 1z; + i /= 10i64; + }; + + const x: size = if (isneg) 1z else 0z; + bytes::reverse(s.b[x..s.l]); + + s.b[s.l] = 0u8; + return *(&s: *str); +}; + +// Converts an i8 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::i8tos(123); +// io::printf("%s", a); // 123 +// +// let a = strconv::i8tos(123); +// let b = strconv::i8tos(321); +// io::printf("%s %s", a, b); // 321 321 +export fn i8tos(i: i8) const str = i64tos(i: i64); + +// Converts an i16 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::i16tos(1234); +// io::printf("%s", a); // 1234 +// +// let a = strconv::i16tos(1234); +// let b = strconv::i16tos(4321); +// io::printf("%s %s", a, b); // 4321 4321 +export fn i16tos(i: i16) const str = i64tos(i: i64); + +// Converts an i32 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::i32tos(1234); +// io::printf("%s", a); // 1234 +// +// let a = strconv::i32tos(1234); +// let b = strconv::i32tos(4321); +// io::printf("%s %s", a, b); // 4321 4321 +export fn i32tos(i: i32) const str = i64tos(i: i64); + +// Converts an int to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::itos(1234); +// io::printf("%s", a); // 1234 +// +// let a = strconv::itos(1234); +// let b = strconv::itos(4321); +// io::printf("%s %s", a, b); // 4321 4321 +export fn itos(i: int) const str = i64tos(i: i64); diff --git a/strconv/numeric.ha b/strconv/numeric.ha @@ -0,0 +1,45 @@ +use types; + +// Converts any types::signed to a string in base 10. The return value is +// statically allocated and will be overwritten on subsequent calls; see +// [strings::dup] to duplicate the result, or [strconv::itosb] to pass your own +// string buffer. +// +// let a = strconv::signedtos(123); +// io::printf("%s", a); // 123 +// +// let a = strconv::signedtos(123); +// let b = strconv::signedtos(321); +// io::printf("%s %s", a, b); // 321 321 +export fn signedtos(n: types::signed) const str = { + return match (n) { + i: int => itos(i), + i: i8 => i8tos(i), + i: i16 => i16tos(i), + i: i32 => i32tos(i), + i: i64 => i64tos(i), + }; +}; + +// Converts any types::unsigned to a string in base 10. The return value is +// statically allocated and will be overwritten on subsequent calls; see +// [strings::dup] to duplicate the result, or [strconv::itosb] to pass your own +// string buffer. +// +// let a = strconv::unsignedtos(123); +// io::printf("%s", a); // 123 +// +// let a = strconv::unsignedtos(123); +// let b = strconv::unsignedtos(321); +// io::printf("%s %s", a, b); // 321 321 +export fn unsignedtos(n: (...types::unsigned | uintptr)) const str = { + return match (n) { + u: size => ztos(u), + u: uint => utos(u), + u: uintptr => uptrtos(u), + u: u8 => u8tos(u), + u: u16 => u16tos(u), + u: u32 => u32tos(u), + u: u64 => u64tos(u), + }; +}; diff --git a/strconv/utos.ha b/strconv/utos.ha @@ -0,0 +1,111 @@ +use bytes; +use types; + +// Converts a u64 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::u64tos(1234u); +// io::printf("%s", a); // 1234 +// +// let a = strconv::u64tos(1234u); +// let b = strconv::u64tos(4321u); +// io::printf("%s %s", a, b); // 4321 4321 +export fn u64tos(u: u64) const str = { + static assert(types::U64_MAX == 18446744073709551615u64); + static let buf: [21]u8 = [0u8...]; // 20 digits plus NUL + buf = [0u8...]; + + let s = struct { + b: *[*]u8 = &buf, + l: size = 0z, + c: size = 0z, + }; + + if (u == 0u64) { + s.b[s.l] = '0': u32: u8; + s.l += 1z; + }; + + for (u > 0u64) { + s.b[s.l] = '0': u32: u8 + (u % 10u64): u8; + s.l += 1z; + u /= 10u64; + }; + + bytes::reverse(s.b[..s.l]); + s.b[s.l] = 0u8; + return *(&s: *str); +}; + +// Converts a u8 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::u64tos(123u); +// io::printf("%s", a); // 123 +// +// let a = strconv::u64tos(123u); +// let b = strconv::u64tos(321u); +// io::printf("%s %s", a, b); // 321 321 +export fn u8tos(u: u8) const str = u64tos(u: u64); + +// Converts a u16 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::u16tos(1234u); +// io::printf("%s", a); // 1234 +// +// let a = strconv::u16tos(1234u); +// let b = strconv::u16tos(4321u); +// io::printf("%s %s", a, b); // 4321 4321 +export fn u16tos(u: u16) const str = u64tos(u: u64); + +// Converts a u32 to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::u32tos(1234u); +// io::printf("%s", a); // 1234 +// +// let a = strconv::u32tos(1234u); +// let b = strconv::u32tos(4321u); +// io::printf("%s %s", a, b); // 4321 4321 +export fn u32tos(u: u32) const str = u64tos(u: u64); + +// Converts a uint to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::utos(1234u); +// io::printf("%s", a); // 1234 +// +// let a = strconv::utos(1234u); +// let b = strconv::utos(4321u); +// io::printf("%s %s", a, b); // 4321 4321 +export fn utos(u: uint) const str = u64tos(u: u64); + +// Converts a size to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::ztos(1234u); +// io::printf("%s", a); // 1234 +// +// let a = strconv::ztos(1234u); +// let b = strconv::ztos(4321u); +// io::printf("%s %s", a, b); // 4321 4321 +export fn ztos(z: size) const str = u64tos(z: u64); + +// Converts a uintptr to a string, in base 10. The return value is statically +// allocated and will be overwritten on subsequent calls; see [strings::dup] to +// duplicate the result, or [strconv::itosb] to pass your own string buffer. +// +// let a = strconv::uptrtos(1234u); +// io::printf("%s", a); // 1234 +// +// let a = strconv::uptrtos(1234u); +// let b = strconv::uptrtos(4321u); +// io::printf("%s %s", a, b); // 4321 4321 +export fn uptrtos(uptr: uintptr) const str = u64tos(uptr: u64);