From 0a424ec6d2d54bd424f069bbbca2186b529579c5 Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Sun, 12 Jul 2026 21:02:12 +0200 Subject: [PATCH] mem.eql (stdlib) --- LANGUAGE.md | 2 +- TODO.md | 2 +- compiler/checker/checker.odin | 14 ++++++++++++++ examples/programs/mem_allocator/main.bro | 21 +++++++++++++++++++++ std/mem/mem.bro | 14 ++++++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/LANGUAGE.md b/LANGUAGE.md index adcc71c..2e573fe 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -77,7 +77,7 @@ roadmap and milestone history. ### standard packages -- `std/mem` allocator contract with raw byte operations, typed `empty` / `alloc` / `realloc` / `free`, overflow checks, zero-sized-type support, and failure-preserving reallocation +- `std/mem` generic slice equality, allocator contract with raw byte operations, typed `empty` / `alloc` / `realloc` / `free`, overflow checks, zero-sized-type support, and failure-preserving reallocation - `std/arraylist` generic `ArrayList(T)` with direct `items` slice access, explicit capacity, allocator ownership, fallible reserve/append, clear, and deinit ### compiler behavior diff --git a/TODO.md b/TODO.md index e4362e3..bb47574 100644 --- a/TODO.md +++ b/TODO.md @@ -794,7 +794,7 @@ 32. disallow arbitrary integer division - take inspiration from zig - see also below for a word on unchecked casts - - the user should be explicit about what they mean with integer division (e.g. `div`, `rem`, `trunc`) + - the user should be explicit about what they mean with integer division (e.g. `div`, `rem`) ## A word on unchecked casts diff --git a/compiler/checker/checker.odin b/compiler/checker/checker.odin index 915b457..8e13a20 100644 --- a/compiler/checker/checker.odin +++ b/compiler/checker/checker.odin @@ -1350,6 +1350,20 @@ match_inferred_type_pattern :: proc( return matched } actual_item, actual_ok := types.node(store, actual_type) + if pattern_item.kind == .Slice { + actual_pointer, actual_array, array_pointer_ok := types.array_pointer(actual_type, store) + if array_pointer_ok { + mutable := actual_pointer.mutable && actual_array.mutable + if pattern_item.mutable && !mutable || + pattern_item.has_sentinel && (!actual_array.has_sentinel || pattern_item.sentinel != actual_array.sentinel) { + return false + } + return match_inferred_type_pattern( + checker, function, prefix, pattern_item.child, actual_array.child, + values, bound, span, diagnose, depth+1, + ) + } + } if !actual_ok || pattern_item.kind != actual_item.kind { resolved := type_from_syntax(checker, pattern, function.pkg, function.file) return types.is_valid(resolved) && types.equal(types.resolve_alias(resolved, store), actual_type) diff --git a/examples/programs/mem_allocator/main.bro b/examples/programs/mem_allocator/main.bro index 9cca642..8a6bdc4 100644 --- a/examples/programs/mem_allocator/main.bro +++ b/examples/programs/mem_allocator/main.bro @@ -1,4 +1,25 @@ +mem :: import "@std/mem" + +eql_test func() i32 { + if (mem.eql("bro", "bro") == false) return 21 + if mem.eql("bro", "bra") return 22 + if mem.eql("bro", "brolang") return 23 + + empty []u8 :: "" + if (mem.eql(empty, "") == false) return 24 + + left [3]i32 :: [1, 2, 3] + same [3]i32 :: [1, 2, 3] + different [3]i32 :: [1, 2, 4] + if (mem.eql(left[..], same[..]) == false) return 25 + if mem.eql(left[..], different[..]) return 26 + return 0 +} + main func() i32 { + eql_result i32 :: eql_test() + if (eql_result != 0) return eql_result + typed_result i32 :: typed_allocator_test() if (typed_result != 0) return typed_result diff --git a/std/mem/mem.bro b/std/mem/mem.bro index 2cc32c3..2f3ad18 100644 --- a/std/mem/mem.bro +++ b/std/mem/mem.bro @@ -27,6 +27,20 @@ raw_free func(allocator Allocator, memory ?*mut u8, size usize, alignment usize) allocator.vtable.free(allocator.context, memory, size, alignment) } +eql func($T type, left, right []T) bool { + if left.len != right.len { + return false + } + + i usize = 0 + while i < left.len : i += 1 { + if left[i] != right[i] { + return false + } + } + return true +} + _empty_storage [1]mut u64 = [0] _empty_slice func($T type, count usize) []mut T {