From 5b123be9ea1f10e6ccc69b564b8d6d777a9493b6 Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Sun, 22 Dec 2024 19:48:12 +0000
Subject: [PATCH] semi-broken again

---
 Cargo.lock                                    |  14 +-
 sysdata/libraries/stn/src/buffer.hb           |  10 +-
 sysdata/libraries/stn/src/file_io.hb          |   2 +-
 sysdata/libraries/stn/src/fmt.hb              | 198 +++++++++---------
 sysdata/libraries/stn/src/lib.hb              |   4 +-
 sysdata/libraries/stn/src/log.hb              |  25 +--
 sysdata/libraries/stn/src/string.hb           | 196 ++++++++---------
 sysdata/programs/test/src/tests/stn/fmt.hb    |   5 +-
 .../programs/test/src/tests/stn/hashers.hb    |  16 +-
 sysdata/programs/vfsaur/src/main.hb           |  33 ++-
 sysdata/system_config.toml                    |   8 +-
 11 files changed, 255 insertions(+), 256 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 108c3ed..4a13d71 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,9 +19,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
 
 [[package]]
 name = "anyhow"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
 
 [[package]]
 name = "autocfg"
@@ -213,12 +213,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#418fd0039eda7fd4052c8086373b1e1257d573c8"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9c4b84ce33ea6ac7fe0f1b00ee5c67718643a34a"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#418fd0039eda7fd4052c8086373b1e1257d573c8"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9c4b84ce33ea6ac7fe0f1b00ee5c67718643a34a"
 dependencies = [
  "hashbrown",
  "hbbytecode",
@@ -229,7 +229,7 @@ dependencies = [
 [[package]]
 name = "hbvm"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#418fd0039eda7fd4052c8086373b1e1257d573c8"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9c4b84ce33ea6ac7fe0f1b00ee5c67718643a34a"
 dependencies = [
  "hbbytecode",
 ]
@@ -726,9 +726,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
 
 [[package]]
 name = "syn"
-version = "2.0.90"
+version = "2.0.91"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
+checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/sysdata/libraries/stn/src/buffer.hb b/sysdata/libraries/stn/src/buffer.hb
index 9e0866a..346ca0b 100644
--- a/sysdata/libraries/stn/src/buffer.hb
+++ b/sysdata/libraries/stn/src/buffer.hb
@@ -22,9 +22,8 @@ $write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
 
 BufferMsg := packed struct {operation: u8, msg: ^u8, msg_len: uint}
 
-create := fn(msg: ^u8): uint {
-	// for some reason not inlining here breaks things
-	return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
+$create := fn(msg: []u8): uint {
+	return @eca(3, 0, BufferMsg.(0, msg.ptr, msg.len), @sizeof(BufferMsg))
 }
 
 $create_nameless := fn(): uint {
@@ -35,7 +34,6 @@ $delete_buffer := fn(buffer_id: uint): void {
 	return @eca(2, buffer_id)
 }
 
-search := fn(msg: ^u8): uint {
-	// for some reason not inlining here breaks things
-	return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
+$search := fn(msg: []u8): uint {
+	return @eca(3, 0, BufferMsg.(3, msg.ptr, msg.len), @sizeof(BufferMsg))
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/file_io.hb b/sysdata/libraries/stn/src/file_io.hb
index 2664c24..8b3ec80 100644
--- a/sysdata/libraries/stn/src/file_io.hb
+++ b/sysdata/libraries/stn/src/file_io.hb
@@ -2,7 +2,7 @@ acs := @use("acs.hb");
 .{DiskID, FileID} := acs
 
 // Paths without a node-disk component are to be treated as local files.
-// file_path := "DID:/test\0";
+// file_path := "DID:/test\0"
 Path := struct {
 	// DiskID holds the host id
 	disk_id: DiskID,
diff --git a/sysdata/libraries/stn/src/fmt.hb b/sysdata/libraries/stn/src/fmt.hb
index 78294ce..1763874 100644
--- a/sysdata/libraries/stn/src/fmt.hb
+++ b/sysdata/libraries/stn/src/fmt.hb
@@ -1,178 +1,172 @@
 .{Kind, usize, string, signed_int, panic, float, integer, memory, log: .{LogLevel}} := @use("stn")
 
-fmt_int := fn(v: @Any(), str: ^u8, radix: @TypeOf(v)): uint {
+fmt_int := fn(v: @Any(), str: []u8, radix: @TypeOf(v)): uint {
 	is_negative := signed_int(@TypeOf(v)) & v < 0
-	if is_negative v = -v
-
 	prefix_len := 0
+	if is_negative {
+		v = -v
+		str[0] = '-'
+		prefix_len += 1
+	}
+
 	if radix == 16 {
-		*str = '0';
-		*(str + 1) = 'x'
-		prefix_len = 2
+		*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0x".ptr)
+		prefix_len += 2
 	} else if radix == 2 {
-		*str = '0';
-		*(str + 1) = 'b'
-		prefix_len = 2
+		*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0b".ptr)
+		prefix_len += 2
 	} else if radix == 8 {
-		*str = '0';
-		*(str + 1) = 'o'
-		prefix_len = 2
+		*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0o".ptr)
+		prefix_len += 2
 	}
 
 	if v == 0 {
-		*(str + prefix_len) = '0'
+		str[prefix_len] = '0'
 		return prefix_len + 1
 	}
 
-	i := 0
+	i := prefix_len
 	loop if v <= 0 break else {
 		remainder := v % radix
 		v /= radix
 		if remainder > 9 {
-			*(str + prefix_len + i) = @intcast(remainder - 10 + 'A')
+			str[i] = @intcast(remainder - 10 + 'A')
 		} else {
-			*(str + prefix_len + i) = @intcast(remainder + '0')
+			str[i] = @intcast(remainder + '0')
 		}
 		i += 1
 	}
 
-	if is_negative {
-		*(str + prefix_len + i) = '-'
-		i += 1
-	}
-
-	@inline(string.reverse, str + prefix_len)
-	return prefix_len + i
+	string.reverse(str[prefix_len..i])
+	return i
 }
 
-fmt_bool := fn(v: bool, str: ^u8): uint {
+fmt_bool := fn(v: bool, str: []u8): uint {
 	if v {
-		*@as(^[4]u8, @bitcast(str)) = *@bitcast("true\0")
+		*@as(^[4]u8, @bitcast(str.ptr)) = *@bitcast("true".ptr)
 		return 4
 	} else {
-		*@as(^[5]u8, @bitcast(str)) = *@bitcast("false\0")
+		*@as(^[5]u8, @bitcast(str.ptr)) = *@bitcast("false".ptr)
 		return 5
 	}
 }
 
-fmt_float := fn(v: @Any(), str: ^u8, precision: uint, radix: int): uint {
+$FP_TOLERANCE := 0.00000001
+
+fmt_float := fn(v: @Any(), str: []u8, precision: uint, radix: int): uint {
 	is_negative := v < 0
-	i := 0
 
 	prefix_len := 0
-	if radix == 16 {
-		*str = '0';
-		*(str + 1) = 'x'
-		prefix_len = 2
-	} else if radix == 2 {
-		*str = '0';
-		*(str + 1) = 'b'
-		prefix_len = 2
-	} else if radix == 8 {
-		*str = '0';
-		*(str + 1) = 'o'
-		prefix_len = 2
+
+	if is_negative {
+		v = -v
+		str[0] = '-'
+		prefix_len += 1
 	}
 
-	if is_negative v = -v
+	if radix == 16 {
+		*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0x".ptr)
+		prefix_len += 2
+	} else if radix == 2 {
+		*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0b".ptr)
+		prefix_len += 2
+	} else if radix == 8 {
+		*@as(^[2]u8, @bitcast(str.ptr + prefix_len)) = *@bitcast("0o".ptr)
+		prefix_len += 2
+	}
 
 	integer_part := @fti(v)
 	fractional_part := v - @itf(integer_part)
 
-	loop if integer_part == 0 & i > 0 break else {
+	i := prefix_len
+	loop if integer_part == 0 & i > prefix_len break else {
 		remainder := integer_part % radix
 		integer_part /= radix
 		if remainder > 9 {
-			*(str + prefix_len + i) = @intcast(remainder - 10 + 'A')
+			str[i] = @intcast(remainder - 10 + 'A')
 		} else {
-			*(str + prefix_len + i) = @intcast(remainder + '0')
+			str[i] = @intcast(remainder + '0')
 		}
 		i += 1
 	}
 
-	if is_negative {
-		*(str + prefix_len + i) = '-'
-		i += 1
-	}
-
-	@inline(string.reverse, str + prefix_len);
-	*(str + prefix_len + i) = '.'
+	string.reverse(str[prefix_len..i])
+	str[i] = '.'
 	i += 1
 
 	p := precision
-	tolerance := @as(@TypeOf(v), 0.00000001)
-	loop if p <= 0 | fractional_part < tolerance break else {
+	loop if p <= 0 | fractional_part < FP_TOLERANCE break else {
 		fractional_part *= @itf(radix)
 		digit := @fti(fractional_part)
 		if digit > 9 {
-			*(str + prefix_len + i) = @intcast(digit - 10 + 'A')
+			str[i] = @intcast(digit - 10 + 'A')
 		} else {
-			*(str + prefix_len + i) = @intcast(digit + '0')
+			str[i] = @intcast(digit + '0')
 		}
 		i += 1
 		fractional_part -= @itf(digit)
 		p -= 1
 	}
 
-	return prefix_len + i
+	return i
 }
 
-fmt_container := fn(v: @Any(), str: ^u8, opts: FormatOptions): uint {
+fmt_container := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
 	T2 := @TypeOf(v)
 	kind := Kind.of(T2)
 	i := 0
 	len := 0
 	if kind == .Struct {
-		*@as(^[@lenof(@nameof(T2))]u8, @bitcast(str + len)) = *@bitcast(@nameof(T2))
-		len += @lenof(@nameof(T2));
-		*@as(^[2]u8, @bitcast(str + len)) = *@bitcast(".(\0")
+		*@as(^[@intcast(@nameof(T2).len)]u8, @bitcast(str.ptr + len)) = *@bitcast(@nameof(T2).ptr)
+		len += @nameof(T2).len;
+		*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
 		len += 2
 	} else if kind == .Slice {
-		*@as(^[@lenof(@nameof(@ChildOf(T2)))]u8, @bitcast(str + len)) = *@bitcast(@nameof(@ChildOf(T2)))
-		len += @lenof(@nameof(@ChildOf(T2)));
-		*@as(^[2]u8, @bitcast(str + len)) = *@bitcast(".[\0")
+		*@as(^[@intcast(@nameof(@ChildOf(T2)).len)]u8, @bitcast(str.ptr + len)) = *@bitcast(@nameof(@ChildOf(T2)).ptr)
+		len += @nameof(@ChildOf(T2)).len;
+		*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".[".ptr)
 		len += 2
 	} else if kind == .Tuple {
-		*@as(^[2]u8, @bitcast(str + len)) = *@bitcast(".(\0")
+		*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
 		len += 2
 	}
 	$loop {
 		v_sub := v[i]
-		len += @inline(format, v_sub, str + len, opts)
+		len += @inline(format, v_sub, str[len..], opts)
 		i += 1
 		if i == @lenof(T2) break else {
-			*@as(^[2]u8, @bitcast(str + len)) = *@bitcast(", \0")
+			*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(", ".ptr)
 			len += 2
 		}
 	}
 	if kind == .Struct | kind == .Tuple {
-		*@as(^[1]u8, @bitcast(str + len)) = *@bitcast(")\0")
+		*@as(^[1]u8, @bitcast(str.ptr + len)) = *@bitcast(")".ptr)
 		len += 1
 	} else if kind == .Slice {
-		*@as(^[1]u8, @bitcast(str + len)) = *@bitcast("]\0")
+		*@as(^[1]u8, @bitcast(str.ptr + len)) = *@bitcast("]".ptr)
 		len += 1
 	}
 	return len
 }
 
-fmt_nullable := fn(v: @Any(), str: ^u8, opts: FormatOptions): uint {
+fmt_nullable := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
 	if v == null {
-		*@as(^[4]u8, @bitcast(str)) = *@bitcast("null\0")
+		*@as(^[4]u8, @bitcast(str.ptr)) = *@bitcast("null".ptr)
 		return 4
 	} else {
 		return @inline(format, @as(@ChildOf(@TypeOf(v)), v), str, opts)
 	}
 }
 
-fmt_enum := fn(v: @Any(), str: ^u8, opts: FormatOptions): uint {
+fmt_enum := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
 	T := @TypeOf(v)
-	len := @lenof(@nameof(T));
-	*@as(^[@lenof(@nameof(T))]u8, @bitcast(str)) = *@bitcast(@nameof(T));
-	*@as(^[2]u8, @bitcast(str + len)) = *@bitcast(".(\0")
+	len := @nameof(T).len;
+	*@as(^[@intcast(@nameof(T).len)]u8, @bitcast(str.ptr)) = *@bitcast(@nameof(T).ptr);
+	*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
 	len += 2
-	len += @inline(fmt_int, @as(usize(T), @bitcast(v)), str + len, 10);
-	*@as(^[2]u8, @bitcast(str + len)) = *@bitcast(")\0")
-	return len + 2
+	len += fmt_int(@as(usize(T), @bitcast(v)), str[len..], 10);
+	*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(")".ptr)
+	return len + 1
 }
 
 /* TODO:
@@ -196,17 +190,10 @@ FormatOptions := struct {
  * Does not clear the buffer for you
 */
 
-format := fn(v: @Any(), str: ^u8, opts: FormatOptions): uint {
+format := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
 	T := @TypeOf(v)
 	match Kind.of(T) {
-		.Pointer => if T != ^u8 return @inline(fmt_int, @as(uint, @bitcast(v)), str, 16) else {
-			i := 0
-			loop if *(v + i) == '\0' break else {
-				*(str + i) = *(v + i)
-				i += 1
-			}
-			return i
-		},
+		.Pointer => return @inline(fmt_int, @as(uint, @bitcast(v)), str, 16),
 		.Builtin => {
 			if integer(T) {
 				return @inline(fmt_int, v, str, @intcast(opts.radix))
@@ -220,37 +207,44 @@ format := fn(v: @Any(), str: ^u8, opts: FormatOptions): uint {
 		.Enum => return @inline(fmt_enum, v, str, opts),
 		.Struct => return @inline(fmt_container, v, str, opts),
 		.Tuple => return @inline(fmt_container, v, str, opts),
-		.Slice => return @inline(fmt_container, v, str, opts),
-		_ => @error("Type: \"\0", T, "\" is not supported.\0"),
+		.Slice => if T != []u8 return @inline(fmt_container, v, str, opts) else {
+			i := 0
+			loop if i == v.len break else {
+				str[i] = v[i]
+				i += 1
+			}
+			return v.len
+		},
+		_ => @error("Type: \"", T, "\" is not supported."),
 	}
 }
 
-format_with_str := fn(v: @Any(), read: ^u8, write: ^u8, opts: FormatOptions): uint {
+format_with_str := fn(v: @Any(), read: []u8, write: []u8, opts: FormatOptions): uint {
 	T := @TypeOf(v)
 	n := string.count(read, '{')
-	if n != string.count(read, '}') panic("Missing closing '}' in format string.\0")
+	if n != string.count(read, '}') panic("Missing closing '}' in format string.")
 	if Kind.of(T) == .Tuple {
-		if @lenof(T) != n panic("Format string has different number of '{}' than args given.\0")
+		if @lenof(T) != n panic("Format string has different number of '{}' than args given.")
 		m := 0
 		i := 0
 		j := 0
 		$loop if m > @lenof(T) break else {
 			if m == @lenof(T) {
-				loop if *(read + i) == '\0' break else {
-					*(write + j) = *(read + i)
+				loop if i == read.len break else {
+					write[j] = read[i]
 					i += 1
 					j += 1
 				}
 				m += 1
 			} else {
 				v2 := v[m]
-				loop if *(read + i) == '\0' break else {
-					if *(read + i) == '{' & *(read + i + 1) == '}' {
-						j += format(v2, write + j, opts) + 1
+				loop if i == read.len break else {
+					if read[i] == '{' & read[i + 1] == '}' {
+						j += format(v2, write[j..], opts)
 						i += 2
 						break
 					} else {
-						*(write + j) = *(read + i)
+						write[j] = read[i]
 						i += 1
 						j += 1
 					}
@@ -260,16 +254,16 @@ format_with_str := fn(v: @Any(), read: ^u8, write: ^u8, opts: FormatOptions): ui
 		}
 		return j
 	} else if n > 1 {
-		panic("Format string has multiple '{}' but value provided is not a tuple.\0")
+		panic("Format string has multiple '{}' but value provided is not a tuple.")
 	} else {
 		i := 0
 		j := 0
-		loop if *(read + i) == '\0' break else {
-			if *(read + i) == '{' & *(read + i + 1) == '}' {
-				j += format(v, write + j, opts) + 1
+		loop if i == read.len break else {
+			if read[i] == '{' & read[i + 1] == '}' {
+				j += format(v, write[j..], opts)
 				i += 2
 			} else {
-				*(write + j) = *(read + i)
+				write[j] = read[i]
 				i += 1
 				j += 1
 			}
diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb
index e5108b8..5354088 100644
--- a/sysdata/libraries/stn/src/lib.hb
+++ b/sysdata/libraries/stn/src/lib.hb
@@ -13,8 +13,8 @@ dt := @use("dt.hb")
 process := @use("process.hb")
 sleep := @use("sleep.hb")
 
-panic := fn(message: ?^u8): never {
-	log.printf("HBLang Panic: {}\0", message, .{log: .Error})
+panic := fn(message: ?[]u8): never {
+	log.printf("HBLang Panic: {}", message, .{log: .Error})
 	die
 }
 
diff --git a/sysdata/libraries/stn/src/log.hb b/sysdata/libraries/stn/src/log.hb
index 483c742..4acc477 100644
--- a/sysdata/libraries/stn/src/log.hb
+++ b/sysdata/libraries/stn/src/log.hb
@@ -10,15 +10,15 @@ LogLevel := enum {
 	Trace,
 }
 
-log := fn(level: LogLevel, message: ^u8): void {
-	return @eca(3, 1, LogMsg.(level, message, @inline(string.length, message)), @sizeof(LogMsg))
+$log := fn(level: LogLevel, message: []u8): void {
+	return @eca(3, 1, LogMsg.(level, message.ptr, message.len), @sizeof(LogMsg))
 }
 
-error := fn(message: ^u8): void return @inline(log, LogLevel.Error, message)
-warn := fn(message: ^u8): void return @inline(log, LogLevel.Warn, message)
-info := fn(message: ^u8): void return @inline(log, LogLevel.Info, message)
-debug := fn(message: ^u8): void return @inline(log, LogLevel.Debug, message)
-trace := fn(message: ^u8): void return @inline(log, LogLevel.Trace, message)
+$error := fn(message: []u8): void return log(LogLevel.Error, message)
+$warn := fn(message: []u8): void return log(LogLevel.Warn, message)
+$info := fn(message: []u8): void return log(LogLevel.Info, message)
+$debug := fn(message: []u8): void return log(LogLevel.Debug, message)
+$trace := fn(message: []u8): void return log(LogLevel.Trace, message)
 
 print_buffer := memory.dangling(u8)
 
@@ -26,16 +26,17 @@ print := fn(v: @Any(), opts: fmt.FormatOptions): void {
 	if print_buffer == memory.dangling(u8) {
 		print_buffer = memory.request_page(1)
 	}
-	len := @inline(fmt.format, v, print_buffer, opts)
+	len := @inline(fmt.format, v, print_buffer[0..memory.PAGE_SIZE], opts)
 	@eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg))
-	memory.set(u8, &0, print_buffer, memory.PAGE_SIZE)
+	memory.set(u8, &0, print_buffer, len)
 }
 
-printf := fn(str: ^u8, v: @Any(), opts: fmt.FormatOptions): void {
+printf := fn(str: []u8, v: @Any(), opts: fmt.FormatOptions): void {
 	if print_buffer == memory.dangling(u8) {
 		print_buffer = memory.request_page(1)
 	}
-	len := @inline(fmt.format_with_str, v, str, print_buffer, opts)
+	len := @inline(fmt.format_with_str, v, str, print_buffer[0..memory.PAGE_SIZE], opts)
 	@eca(3, 1, LogMsg.(opts.log, print_buffer, len), @sizeof(LogMsg))
-	memory.set(u8, &0, print_buffer, memory.PAGE_SIZE)
+	print(len, .{})
+	memory.set(u8, &0, print_buffer, len)
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/string.hb b/sysdata/libraries/stn/src/string.hb
index b57b918..dcf7db9 100644
--- a/sysdata/libraries/stn/src/string.hb
+++ b/sysdata/libraries/stn/src/string.hb
@@ -1,107 +1,118 @@
 .{log, memory} := @use("stn")
 
-length := fn(ptr: ^u8): uint {
-	len := 0
-	loop if *(ptr + len) == 0 return len else len += 1
-}
-
-reverse := fn(s: ^u8): void {
-	j := s + @inline(length, s) - 1
+reverse := fn(str: []u8): void {
+	if str.len == 0 return;
+	j := str.len - 1
+	i := 0
 	temp := @as(u8, 0)
-	loop if s < j {
-		temp = *s;
-		*s = *j;
-		*j = temp
-		s += 1
+	loop if i < j {
+		temp = str[i]
+		str[i] = str[j]
+		str[j] = temp
+		i += 1
 		j -= 1
 	} else return
 }
 
-equals := fn(lhs: ^u8, rhs: ^u8): bool {
-	if lhs == rhs {
-		return true
-	}
-	loop if *lhs != *rhs {
-		return false
-	} else if *lhs == 0 {
-		return true
-	} else {
-		lhs += 1
-		rhs += 1
+$equals := fn(lhs: []u8, rhs: []u8): bool {
+	return lhs.ptr == rhs.ptr & lhs.len == rhs.len
+}
+
+clear := fn(str: []u8): void {
+	i := 0
+	loop if i == str.len break else {
+		str[i] = 0
+		i += 1
 	}
 }
 
-clear := fn(ptr: ^u8): void {
-	loop if *ptr == 0 break else {
-		*ptr = 0
-		ptr += 1
-	}
-}
-
-split_buffer := memory.dangling(u8)
-
-split_once := fn(haystack: ^u8, needle: @Any()): ?^u8 {
+split_once := fn(haystack: []u8, needle: @Any()): ?[]u8 {
 	T := @TypeOf(needle)
-	if T == ^u8 {
-		if *needle == 0 return null
-
-		loop if *haystack == 0 return null else {
-			if *haystack == *needle {
-				h := haystack
-				n := needle
+	if T == []u8 {
+		if needle.len == 0 return null
+		i := 0
+		loop if i == haystack.len return null else {
+			if haystack[i] == needle[0] {
+				h := i
+				n := 0
 
 				loop {
 					n += 1
 					h += 1
-					if *n == 0 {
-						return haystack
-					} else if *h == 0 | *h != *n {
+					if needle[n] == 0 {
+						return haystack[h..]
+					} else if haystack[h] == 0 | haystack[h] != needle[n] {
 						break
 					}
 				}
 			}
-			haystack += 1
+			i += 1
 		}
 	} else if T == u8 {
-		loop if *haystack == needle return haystack else if *haystack == 0 return null else haystack += 1
+		i := 0
+		loop if haystack[i] == needle return haystack[i..] else if i == haystack.len return null else i += 1
 	} else {
-		@error("Type of needle must be string or char.\0")
+		@error("Type of needle must be []u8 or u8.")
 	}
 }
 
 SplitIter := fn($T: type): type {
 	return struct {
-		str: ^u8,
+		str: []u8,
 		needle: T,
 		done: bool,
 
-		next := fn(self: ^Self): ?^u8 {
-			if self.done | *self.str == 0 {
-				return null
+		next := fn(self: ^Self): ?[]u8 {
+			if self.done return null;
+
+			if @TypeOf(self.needle) == u8 {
+				i := 0
+				loop if i == self.str.len {
+					self.done = true
+					return self.str
+				} else if self.str[i] == self.needle {
+					result := self.str[..i]
+					self.str = self.str[i + 1..]
+					return result
+				} else {
+					i += 1
+				}
+			} else if @TypeOf(self.needle) == []u8 {
+				if self.needle.len == 0 return null
+				i := 0
+				loop if i == self.str.len {
+					self.done = true
+					return self.str
+				} else if self.str[i] == self.needle[0] {
+					h := i
+					n := 0
+
+					loop {
+						n += 1
+						h += 1
+
+						if n == self.needle.len {
+							result := self.str[..i]
+							self.str = self.str[h..]
+							return result
+						} else if h == self.str.len | self.str[h] != self.needle[n] {
+							break
+						}
+					}
+				}
+				i += 1
 			}
 
-			next0 := split_once(self.str, self.needle)
-
-			if next0 == null {
-				self.done = true
-				return self.str
-			}
-			s := self.str
-			if T == ^u8 {
-				self.str = next0 + length(self.needle)
-			} else if T == u8 {
-				self.str = next0 + 1
-			}
-
-			return s
+			self.done = true
+			return self.str
 		}
 	}
 }
 
-split := fn(iter: ^u8, needle: @Any()): SplitIter(@TypeOf(needle)) {
+split := fn(iter: []u8, needle: @Any()): SplitIter(@TypeOf(needle)) {
 	T := @TypeOf(needle)
-	if T != ^u8 & T != u8 {
-		@error("Type of needle must be string or char.\0")
+	if T != []u8 & T != u8 {
+		@error("Type of needle must be []u8 or u8.")
 	}
 	return .(iter, needle, false)
 }
@@ -110,53 +121,50 @@ find_once := fn(haystack: ^u8, needle: @Any()): ?uint {
 	return @bitcast(@inline(split_once, haystack, needle) - haystack)
 }
 
-count := fn(haystack: ^u8, needle: @Any()): uint {
+count := fn(haystack: []u8, needle: @Any()): uint {
 	T := @TypeOf(needle)
-	if T != ^u8 & T != u8 {
-		@error("Type of needle must be string or char.\0")
-	}
 	c := 0
 	if T == u8 {
-		loop if *haystack == needle {
+		i := 0
+		loop if haystack[i] == needle {
 			c += 1
-			haystack += 1
-		} else if *haystack == 0 return c else haystack += 1
-	} else if T == ^u8 {
-		if *needle == 0 return 0
-		loop if *haystack == 0 return c else {
-			if *haystack == *needle {
-				h := haystack
-				n := needle
+			i += 1
+		} else if i == haystack.len return c else i += 1
+	} else if T == []u8 {
+		i := 0
+		loop if i == haystack.len return c else {
+			if haystack[i] == needle[0] {
+				h := i
+				n := 0
 
 				loop {
 					n += 1
 					h += 1
-					if *n == 0 {
+					if n == needle.len {
 						c += 1
+						i = h - 1
 						break
-					} else if *h == 0 | *h != *n {
+					} else if h == haystack.len | haystack[h] != needle[n] {
 						break
 					}
 				}
 			}
-			haystack += 1
+			i += 1
 		}
+	} else {
+		@error("Type of needle must be []u8 or u8.")
 	}
 }
 
-left_trim := fn(str: ^u8, sub: ^u8): ^u8 {
-	original := str
-	if *str == *sub {
-		loop if *sub == 0 {
+left_trim := fn(str: []u8, sub: []u8): []u8 {
+	i := 0
+	if str[0] == sub[0] {
+		loop if i == sub.len {
+			return str[i..str.len]
+		} else if str[i] != sub[i] | i == str.len {
 			return str
-		} else if *str != *sub {
-			return original
-		} else if *str == 0 {
-			return original
 		} else {
-			str += 1
-			sub += 1
+			i += 1
 		}
 	}
-	return str
 }
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/stn/fmt.hb b/sysdata/programs/test/src/tests/stn/fmt.hb
index a6f5753..dd95788 100644
--- a/sysdata/programs/test/src/tests/stn/fmt.hb
+++ b/sysdata/programs/test/src/tests/stn/fmt.hb
@@ -19,7 +19,7 @@ EnumThingy := enum {
 
 test := fn(): uint {
 	log.print(@nameof(?u8), .{log: .Error})
-	log.print("Hello, World\0", .{})
+	log.print("Hello, World", .{})
 	log.print(EnumThingy.The, .{})
 	log.print(StructThingy.(-100, -100, .(-math.PI, true)), .{log: .Warn})
 	log.print(SubStructThingy.(-math.E, false), .{})
@@ -30,7 +30,8 @@ test := fn(): uint {
 	log.print(@as(?u32, null), .{})
 	log.print(@as(?u32, 200), .{})
 	log.print(.(@as(?u32, null), 200, 3.14), .{})
-	log.printf("{}, {}, {}\0", .("Hello\0", math.PI, Color.{r: 101, g: 102, b: 103, a: 104}), .{})
+	log.printf("{}, {}, {}", .("Hello", math.PI, Color.{r: 101, g: 102, b: 103, a: 104}), .{})
+	log.printf("{}", "Goodbye", .{})
 
 	return 0
 }
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/stn/hashers.hb b/sysdata/programs/test/src/tests/stn/hashers.hb
index c68e779..354560c 100644
--- a/sysdata/programs/test/src/tests/stn/hashers.hb
+++ b/sysdata/programs/test/src/tests/stn/hashers.hb
@@ -1,26 +1,26 @@
-.{hashers, log, memory, string} := @use("stn")
+.{hashers, log, memory, fmt, string, math} := @use("stn")
 
 test := fn(): uint {
-	target := "abcdefghijklmnop\0"
-	strings := .["abcdefshijklmnop\0", "abcdefghijklnnop\0", "abcdefshijklmnop\0", "abcdefghijklmnop\0", "abcdefghijflmnop\0", "dbcdefghijklmnop\0", "abcdefghijklmnop\0"]
+	target := "abcdefghijklmnop"
+	strings := .["abcdefshijklmnop", "abcdefghijklnnop", "abcdefshijklmnop", "abcdefghijklmnop", "abcdefghijflmnop", "dbcdefghijklmnop", "abcdefghijklmnop"]
 	len := @sizeof(@TypeOf(strings)) / @sizeof(^u8)
-	strlen := string.length(target)
 
 	// hasher := hashers.foldhash.FoldHasher.new(1)
 	hasher := hashers.foldhash.FoldHasher.default()
-	hasher.write(target, strlen)
+	hasher.write(target.ptr, target.len)
 	correct := hasher.finish()
 
-	log.printf("target string: {}, target hash: {}\0", .(target, correct), .{radix: 16})
+	log.printf("target string: {}, target hash: {}", .(target, correct), .{radix: 16})
 
 	i := 0
 	loop if i == len break else {
 		defer i += 1
 
 		hasher.reset()
-		hasher.write(strings[i], strlen)
+		hasher.write(strings[i].ptr, strings[i].len)
 		d := hasher.finish()
-		log.printf("matches: {}, string: {}, hash: {}\0", .(d == correct, strings[i], d), .{radix: 16})
+		log.printf("matches: {}, string: {}, hash: {}", .(d == correct, strings[i], d), .{radix: 16})
 	}
+	log.print("done", .{})
 	return 0
 }
\ No newline at end of file
diff --git a/sysdata/programs/vfsaur/src/main.hb b/sysdata/programs/vfsaur/src/main.hb
index 980d768..9b27539 100644
--- a/sysdata/programs/vfsaur/src/main.hb
+++ b/sysdata/programs/vfsaur/src/main.hb
@@ -8,36 +8,33 @@ stn := @use("stn");
 
 FilesystemServiceListing := struct {
 	// The Root to match against of the file system
-	root: ^u8,
+	root: []u8,
 	// Replace with a slice here soon.
 	// The buffer to forward fs requests to.
 	buffer_id: BufferID,
 }
 
 main := fn(): int {
-	log.info("VFSaur starting.\0")
-	vfs_buff := buffer.create("VFS\0")
+	log.info("VFSaur starting.")
+	vfs_buff := buffer.create("VFS")
 
-	full_path := "acs:/path/to/a/file\0"
+	full_path := "acs:/path/to/a/file"
 	a := parse_str_to_path(full_path)
+	if a != null {
+		log.info(a.root)
+		log.info(a.path)
+	}
 
 	return 0
 }
 
-OSPath := struct {root: ^u8, path: ^u8}
+OSPath := struct {root: []u8, path: []u8}
 
-parse_str_to_path := fn(full_path: ^u8): ?OSPath {
-	split := string.split(full_path, '/')
-	root := split.next()
-	path := split.next()
+parse_str_to_path := fn(full_path: []u8): ?OSPath {
+	path := string.split_once(full_path, '/')
+	if path == null return null;
+
+	root := full_path[..full_path.len - path.len]
 
-	if root == null {
-		log.error("Root is null.\0")
-		return null
-	}
-	if path == null {
-		log.error("Path is null.\0")
-		return null
-	}
 	return OSPath.(root, path)
-}
+}
\ No newline at end of file
diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml
index 798114e..fe4f69a 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -50,8 +50,8 @@ resolution = "1024x768x24"
 # [boot.limine.ableos.modules.angels_halo]
 # path = "boot:///angels_halo.hbf"
 
-#[boot.limine.ableos.modules.test]
-#path = "boot:///test.hbf"
+[boot.limine.ableos.modules.test]
+path = "boot:///test.hbf"
 
-[boot.limine.ableos.modules.vfsaur]
-path = "boot:///vfsaur.hbf"
+# [boot.limine.ableos.modules.vfsaur]
+# path = "boot:///vfsaur.hbf"