From d88513e0051c0d72fa7765e5e77a5add55bd96c6 Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Mon, 5 Oct 2026 18:54:43 +0200 Subject: [PATCH] feat: add typed mem.set --- source/main.hon | 1 + source/sema/resolve.hon | 2 +- std/mem/mem.hon | 6 ++++++ std/mem/mem.test.hon | 24 ++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 std/mem/mem.test.hon diff --git a/source/main.hon b/source/main.hon index 12ab112..27ef5f2 100644 --- a/source/main.hon +++ b/source/main.hon @@ -10,6 +10,7 @@ import "@source/sema" ast_renderer :: import "@source/ast/renderer" +test import "@std/mem" test import "@std/enummap" test import "@std/arraylist" test import "@std/hashmap" diff --git a/source/sema/resolve.hon b/source/sema/resolve.hon index 9a68723..2667ac5 100644 --- a/source/sema/resolve.hon +++ b/source/sema/resolve.hon @@ -58,7 +58,7 @@ resolve proc( ) Resolution ! (mem.AllocError | diagnostics.CapacityError) { bindings :: try mem.alloc(Binding, allocator, ast.node_count(tree)) errdefer mem.free(allocator, bindings) - for (0..bindings.len) |i| bindings[i] = Binding{} + mem.set(bindings, Binding{}) state := State{ tree = tree, diff --git a/std/mem/mem.hon b/std/mem/mem.hon index 4bfa3b7..c84c090 100644 --- a/std/mem/mem.hon +++ b/std/mem/mem.hon @@ -35,6 +35,12 @@ eql proc($T type, left, right []T) bool { return true } +#! assign `value` to each slice element, preserving its typed value rather than repeating a byte. +#! an empty destination is a no-op. +set proc($T type, destination []mut T, value T) void { + for (0..destination.len) |i| destination[i] = value +} + #! allocate memory for a slice of type `T` with `count` elements. alloc proc($T type, allocator Allocator, count usize) []mut T ! AllocError { if (count == 0) return empty_slice(T, 0) diff --git a/std/mem/mem.test.hon b/std/mem/mem.test.hon new file mode 100644 index 0000000..90fc0cf --- /dev/null +++ b/std/mem/mem.test.hon @@ -0,0 +1,24 @@ +import "@std/testing" + +@hide:file +Record :: struct { + tag u8 + id u32 +} + +fills_typed_values_within_slice_boundaries test { + values [4]mut u32 := [1, 2, 3, 4] + set(values[1..3], u32(305419896)) + set(values[2..2], u32(0)) + try testing.expect_equal(u32(1), values[0]) + try testing.expect_equal(u32(305419896), values[1]) + try testing.expect_equal(u32(305419896), values[2]) + try testing.expect_equal(u32(4), values[3]) + + records [2]mut Record := [Record{ tag = 0, id = 0 }, Record{ tag = 0, id = 0 }] + set(records[..], Record{ tag = 3, id = maxval!(u32) }) + for records |record| { + try testing.expect_equal(u8(3), record.tag) + try testing.expect_equal(maxval!(u32), record.id) + } +}