hare

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

commit d2bfe1140f3ea9c3ec454060a5aaedcc3d715b85
parent 8612bf387fc459c1dca36c7e104f369cff53f45a
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 12 Feb 2021 10:07:49 -0500

types: slice and string data is nullable

Diffstat:
Mstrconv/itos.ha | 10+++++-----
Mstrconv/utos.ha | 8++++----
Mstrings/dup.ha | 22++++++++++++++++++----
Mtypes/classes.ha | 4++--
4 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/strconv/itos.ha b/strconv/itos.ha @@ -17,24 +17,24 @@ export fn i64tos(i: i64) const str = { const isneg = i < 0; if (isneg) { - s.data[s.length] = '-': u32: u8; + buf[s.length] = '-': u32: u8; s.length += 1; i = -i; } else if (i == 0) { - s.data[s.length] = '0': u32: u8; + buf[s.length] = '0': u32: u8; s.length += 1; }; for (i > 0) { - s.data[s.length] = '0': u32: u8 + (i % 10): u8; + buf[s.length] = '0': u32: u8 + (i % 10): u8; s.length += 1; i /= 10; }; const x: size = if (isneg) 1 else 0; - bytes::reverse(s.data[x..s.length]); + bytes::reverse(buf[x..s.length]); - s.data[s.length] = 0; + buf[s.length] = 0; return *(&s: *str); }; diff --git a/strconv/utos.ha b/strconv/utos.ha @@ -18,18 +18,18 @@ export fn u64tosb(u: u64, base: uint) const str = { let s = types::string { data = &buf, ... }; if (u == 0) { - s.data[s.length] = '0': u32: u8; + buf[s.length] = '0': u32: u8; s.length += 1z; }; for (u > 0u64) { - s.data[s.length] = lut[(u % base: u64)]: u32: u8; + buf[s.length] = lut[(u % base: u64)]: u32: u8; s.length += 1; u /= base; }; - bytes::reverse(s.data[..s.length]); - s.data[s.length] = 0; + bytes::reverse(buf[..s.length]); + buf[s.length] = 0; return *(&s: *str); }; diff --git a/strings/dup.ha b/strings/dup.ha @@ -4,15 +4,19 @@ use types; // Duplicates a string. Aborts on allocation failure. export fn dup(s: const str) str = { - let in = &s: *types::string; + const in = &s: *types::string; + const id = match (in.data) { + null => return "", // Empty string + b: *[*]u8 => b, + }; let buf: *[*]u8 = match (rt::malloc(in.length + 1)) { null => abort("Out of memory"), v: *void => v, }; - bytes::copy(buf[..in.length + 1z], in.data[..in.length + 1]); + bytes::copy(buf[..in.length + 1z], id[..in.length + 1]); let out = types::string { - data = buf, - length = in.length, + data = buf, + length = in.length, capacity = in.length, }; return *(&out: *str); @@ -25,3 +29,13 @@ export fn dup_all(s: []str) void = { s[i] = strings::dup(s[i]); }; }; + +@test fn dup() void = { + let s = dup(""); + assert(s == ""); + free(s); + + s = dup("hello"); + assert(s == "hello"); + free(s); +}; diff --git a/types/classes.ha b/types/classes.ha @@ -17,7 +17,7 @@ export type numeric = (...integer | ...floating); // string manipulation. export type string = struct { // UTF-8 encoded octets, plus a NUL terminator. - data: *[*]u8, + data: nullable *[*]u8, // The length capacity, in octets of UTF-8 data, not including the NUL // terminator. @@ -32,7 +32,7 @@ export type string = struct { // slice manipulation. export type slice = struct { // The slice contents. - data: *void, + data: nullable *void, // The number of members of the slice. length: size,