migrate to new mutable decl syntax

This commit is contained in:
2026-08-05 21:53:09 +02:00
parent 1689c4db3c
commit 410246faee
20 changed files with 116 additions and 112 deletions
+3 -3
View File
@@ -17,7 +17,7 @@ init proc($T type, allocator mem.Allocator) ArrayList(T) {
}
deinit proc($T type, list @mut ArrayList(T)) void {
allocation []mut T :: list.items.ptr[..list.capacity]
allocation :: list.items.ptr[..list.capacity]
mem.free(list.allocator, allocation)
list.items = mem.empty(T)
list.capacity = 0
@@ -28,9 +28,9 @@ hide reserve proc($T type, list @mut ArrayList(T), min_capacity usize) void ! me
return
}
new_capacity usize = 8
new_capacity := 8
if list.capacity >= 8 {
half usize :: divtrunc!(list.capacity, 2)
half :: divtrunc!(list.capacity, 2)
if list.capacity > maxval!(usize) - half {
new_capacity = min_capacity
} else {
+3 -3
View File
@@ -2,7 +2,7 @@ import "@std/mem"
import "@std/testing"
handles_append test {
list ArrayList(i32) = init(mem.c_allocator)
list ArrayList(i32) := init(mem.c_allocator)
defer deinit(&list)
try append(&list, 42)
@@ -12,7 +12,7 @@ handles_append test {
}
handles_clear test {
list ArrayList(i32) = init(mem.c_allocator)
list ArrayList(i32) := init(mem.c_allocator)
defer deinit(&list)
try append(&list, 42)
@@ -22,7 +22,7 @@ handles_clear test {
}
handles_reserve test {
list ArrayList(i32) = init(mem.c_allocator)
list ArrayList(i32) := init(mem.c_allocator)
defer deinit(&list)
try reserve(&list, 10)
+4 -4
View File
@@ -6,7 +6,7 @@ assert proc(ok bool) void {
}
print proc($format []u8, $Args type, args Args) void {
writer io.Writer :: io.Writer{
writer :: io.Writer{
context = null,
handle = io.Handle{ file_desc = c_int(io.Stream.stderr) },
write = write,
@@ -15,13 +15,13 @@ print proc($format []u8, $Args type, args Args) void {
}
hide write proc(_ ?@mut anyopaque, handle io.Handle, bytes []u8) usize ! io.WriteError {
request usize = bytes.len
maximum usize :: usize(maxval!(c_long))
request := bytes.len
maximum :: usize(maxval!(c_long))
if request > maximum {
request = maximum
}
while true {
count c_long :: c.write(handle.file_desc, bytes.ptr, c_ulong(request))
count :: c.write(handle.file_desc, bytes.ptr, c_ulong(request))
if count >= 0 {
return usize(count)
}
+1 -1
View File
@@ -14,7 +14,7 @@ init proc(
$E, $V type,
values meta.EnumFieldStruct(E, ?V, some!(null)),
) EnumMap(E, V) {
map EnumMap(E, V) = undefined
map EnumMap(E, V) := undefined
match typeinfo!(E) {
.enum |info|: inline for info.fields |field, i| {
+1 -1
View File
@@ -8,7 +8,7 @@ TestEnum :: enum(u8) {
}
handles_sparse_enum_get test {
names EnumMap(TestEnum, []u8) = init({
names EnumMap(TestEnum, []u8) := init({
ident = "identifier",
int = "integer",
})
+5 -5
View File
@@ -59,7 +59,7 @@ get proc(
if (map.count == 0) return null
hash :: normalize(hash_key(key))
idx usize = hash & (map.entries.len - 1)
idx := hash & (map.entries.len - 1)
while true {
entry :: map.entries[idx]
@@ -96,7 +96,7 @@ put proc(
if (entry.hash == 0) continue
# find an empty slot
idx usize = entry.hash & (new_entries.len - 1)
idx := entry.hash & (new_entries.len - 1)
while new_entries[idx].hash != 0 {
idx = (idx + 1) & (new_entries.len - 1)
}
@@ -110,7 +110,7 @@ put proc(
# put new entry
hash :: normalize(hash_key(key))
idx usize = hash & (map.entries.len - 1)
idx := hash & (map.entries.len - 1)
while true {
entry :: map.entries[idx]
@@ -142,8 +142,8 @@ hide normalize proc(hash usize) usize {
#! FNV-1a hash implementation.
#! note: vulnerable to collision attacks.
hide str_hash proc(key []u8) usize {
hash u32 = 2166136261 # offset basis
prime u32 = 16777619
hash u32 := 2166136261 # offset basis
prime u32 := 16777619
for key |byte| {
product u64 :: u64(hash xor u32(byte)) * prime
+1 -1
View File
@@ -2,7 +2,7 @@ import "@std/mem"
import "@std/testing"
handles_put_and_get test {
map StringHashMap(u32) = init(mem.c_allocator)
map StringHashMap(u32) := init(mem.c_allocator)
defer deinit(&map)
try put(&map, "key", 42)
+3 -3
View File
@@ -45,7 +45,7 @@ writer proc(file File) Writer {
}
hide system_read proc(_ ?@mut anyopaque, handle Handle, buffer []mut u8) usize ! ReadError {
request usize = buffer.len
request := buffer.len
maximum usize :: usize(maxval!(c_long))
if (request > maximum) request = maximum
@@ -61,7 +61,7 @@ hide system_read proc(_ ?@mut anyopaque, handle Handle, buffer []mut u8) usize !
}
hide system_write proc(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! WriteError {
request usize = bytes.len
request := bytes.len
maximum usize :: usize(maxval!(c_long))
if (request > maximum) request = maximum
@@ -77,7 +77,7 @@ hide system_write proc(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! Wri
}
hide system_open proc(_ ?@mut anyopaque, path [;0]u8, mode FileMode) Handle ! OpenError {
flags c_int = c.O_RDONLY
flags := c.O_RDONLY
match mode {
.read_only: flags = c.O_RDONLY
.write_only: flags = c.O_WRONLY
+19 -19
View File
@@ -69,7 +69,7 @@ write proc(output Writer, bytes []u8) usize ! WriteError {
}
write_all proc(output Writer, bytes []u8) void ! WriteError {
offset usize = 0
offset usize := 0
while offset < bytes.len {
count usize :: try write(output, bytes[offset..])
if (count == 0) return .no_progress
@@ -120,13 +120,13 @@ print proc(output Writer, $format []u8, $Args type, args Args) void ! WriteError
}
hide write_integer_signed proc(output Writer, value i64, base u64, uppercase bool) void ! WriteError {
buffer [65]mut u8 = undefined
end usize = buffer.len
current i64 = value
buffer [65]mut u8 := undefined
end := buffer.len
current := value
while true {
digit_value i64 :: rem!(current, i64(base))
digit u8 = if (digit_value < 0)
digit := if (digit_value < 0)
u8(-digit_value)
else
u8(digit_value)
@@ -151,9 +151,9 @@ hide write_integer_signed proc(output Writer, value i64, base u64, uppercase boo
}
hide write_integer_unsigned proc(output Writer, value u64, base u64, uppercase bool) void ! WriteError {
buffer [65]mut u8 = undefined
end usize = buffer.len
current u64 = value
buffer [65]mut u8 := undefined
end := buffer.len
current := value
while true {
digit u8 :: u8(rem!(current, base))
@@ -195,12 +195,12 @@ hide FormatToken :: struct {
}
hide parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
tokens [N]mut FormatToken = undefined
tokens [N]mut FormatToken := undefined
for (usize(0))..format.len |index| {
tokens[index] = FormatToken{ kind = .unused, start = 0, end = 0, field = "" }
}
field_count usize = 0
field_count := 0
match typeinfo!(Args) {
.record |r|: {
if (!r.is_tuple) compile_error!("io.print arguments must be a tuple")
@@ -209,10 +209,10 @@ hide parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
else: compile_error!("io.print arguments must be a tuple")
}
token_count usize = 0
argument_count usize = 0
literal_start usize = 0
cursor usize = 0
token_count := 0
argument_count := 0
literal_start := 0
cursor usize := 0
while cursor < format.len {
byte :: format[cursor]
if byte == '{' {
@@ -242,8 +242,8 @@ hide parse_format proc($N usize, $format []u8, $Args type) [N]mut FormatToken {
continue
}
kind FormatTokenKind = .default
width usize = 2
kind FormatTokenKind := .default
width := 2
if next != '}' {
if cursor + 2 >= format.len or format[cursor + 2] != '}' {
compile_error!("io.print format expects a one-character specifier")
@@ -362,8 +362,8 @@ hide write_integer proc(output Writer, $T type, value T, base u64, uppercase boo
hide write_float proc(output Writer, $T type, value T, scientific bool) void ! WriteError {
match typeinfo!(T) {
.float: {
buffer [64]mut u8 = undefined
count c_int = 0
buffer [64]mut u8 := undefined
count := 0
if sizeof!(T) == 4 {
if (scientific) count = c.snprintf(ptrcast!(c_char, (&buffer).ptr), c_ulong(buffer.len), "%.8e", value)
else count = c.snprintf(ptrcast!(c_char, (&buffer).ptr), c_ulong(buffer.len), "%.9g", value)
@@ -403,7 +403,7 @@ hide write_character proc(output Writer, $T type, value T) void ! WriteError {
if minval!(T) < 0 or maxval!(T) > 255 {
compile_error!("io.print '{c}' requires an unsigned integer that fits in u8")
}
buffer [1]u8 = [u8(value)]
buffer [1]u8 := [u8(value)]
try write_all(output, buffer[..])
}
.distinct |backing|: if scalar_or_distinct_type(backing) {
+11 -11
View File
@@ -46,7 +46,7 @@ alloc proc($T type, allocator Allocator, count usize) []mut T ! AllocError {
return .out_of_memory
}
memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T))
memory := raw_alloc(allocator, count * element_size, alignof!(T))
if memory |bytes| {
pointer *mut T :: ptrcast!(T, bytes)
return pointer[..count]
@@ -72,13 +72,13 @@ realloc proc($T type, allocator Allocator, memory []mut T, new_count usize) []mu
if (element_size == 0) return empty_slice(T, new_count)
if (new_count > divtrunc!(maxval!(usize), element_size)) return .out_of_memory
old_memory ?*mut u8 = null
old_size usize = 0
old_memory ?*mut u8 := null
old_size := 0
if memory.len != 0 {
old_memory = ptrcast!(u8, memory.ptr)
old_size = memory.len * element_size
}
resized ?*mut u8 = raw_realloc(
resized := raw_realloc(
allocator,
old_memory,
old_size,
@@ -116,15 +116,15 @@ empty proc($T type) []mut T {
return empty_slice(T, 0)
}
hide empty_storage [1]mut u64 = [0]
hide empty_storage [1]mut u64 := [0]
hide malloc_alignment usize :: 16 # note: aarch64-macos libc malloc alignment assumption.
hide power_of_two proc(value usize) bool {
if (value == 0) return false
current usize = value
current := value
while current > 1 {
half usize = divtrunc!(current, 2)
half := divtrunc!(current, 2)
if (half * 2 != current) return false
current = half
}
@@ -135,8 +135,8 @@ hide c_alloc proc(_ ?@mut anyopaque, size usize, alignment usize) ?*mut u8 {
if (power_of_two(alignment) == false) return null
if (alignment <= malloc_alignment) return ptrcast!(u8, c.malloc(c_ulong(size)))
memory [1]mut ?*mut anyopaque = [null]
status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
memory [1]mut ?*mut anyopaque := [null]
status := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
if (status != 0) return null
return ptrcast!(u8, memory[0])
@@ -161,9 +161,9 @@ hide c_realloc proc(
return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size)))
}
new_memory ?*mut u8 = c_alloc(null, new_size, alignment)
new_memory := c_alloc(null, new_size, alignment)
if new_memory |new_bytes| {
copy_size usize = old_size
copy_size := old_size
if (new_size < copy_size) copy_size = new_size
memcopy!(new_bytes[..copy_size], old_memory[..copy_size])
c.free(old_memory)
+3 -3
View File
@@ -46,9 +46,9 @@ TypeInfo :: union(enum) {
EnumFieldStruct proc($E, $Field type, $default ?Field) type {
match typeinfo!(E) {
.enum |info|: {
names [info.fields.len]mut []u8 = undefined
field_types [info.fields.len]mut type = undefined
defaults [info.fields.len]mut ?Field = undefined
names [info.fields.len]mut []u8 := undefined
field_types [info.fields.len]mut type := undefined
defaults [info.fields.len]mut ?Field := undefined
inline for info.fields |field, index| {
names[index] = field.name
field_types[index] = Field
+2 -2
View File
@@ -42,7 +42,7 @@ distinct_reflection_exposes_immediate_backing test {
enum_field_struct_defaults test {
names TestNames = {
names TestNames := {
ident = "identifier",
int = "integer",
}
@@ -60,7 +60,7 @@ enum_field_struct_defaults test {
try testing.expect(false)
}
empty TestNames = {}
empty TestNames := {}
if field!(empty, "ident") |_| {
try testing.expect(false)
}
+8 -8
View File
@@ -20,8 +20,8 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StringMap(V) {
compile_error!("static string map has too many entries")
}
keys [N]mut []u8 = undefined
values [N]mut V = undefined
keys [N]mut []u8 := undefined
values [N]mut V := undefined
# assert no duplicate keys
for entries |entry, i| {
@@ -38,7 +38,7 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StringMap(V) {
}
if N == 0 {
len_indexes [0]u32 = undefined
len_indexes [0]u32 := undefined
return StringMap(V){
keys = keys[..],
values = values[..],
@@ -52,7 +52,7 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StringMap(V) {
for 1..N |i| {
key :: keys[i]
value :: values[i]
j usize = i
j := i
while j > 0 and keys[j - 1].len > key.len : j -= 1 {
keys[j] = keys[j - 1]
values[j] = values[j - 1]
@@ -63,8 +63,8 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StringMap(V) {
min_len u32 :: u32(keys[0].len)
max_len u32 :: u32(keys[N - 1].len)
len_indexes [usize(max_len) + 1]mut u32 = undefined
entry_index usize = 0
len_indexes [usize(max_len) + 1]mut u32 := undefined
entry_index usize := 0
for 0..=usize(max_len) |length| {
while entry_index < N and keys[entry_index].len < length : entry_index += 1 {}
len_indexes[length] = u32(entry_index)
@@ -82,10 +82,10 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StringMap(V) {
get proc($V type, map @StringMap(V), key []u8) ?V {
if (map.keys.len == 0 or key.len > maxval!(u32)) return null
length u32 = u32(key.len)
length := u32(key.len)
if (length < map.min_len or length > map.max_len) return null
idx usize = usize(map.len_indexes[usize(length)])
idx := usize(map.len_indexes[usize(length)])
while idx < map.keys.len : idx += 1 {
candidate :: map.keys[idx]
if (candidate.len != key.len) return null # key not found
+38 -38
View File
@@ -1,85 +1,85 @@
import "@std/debug"
import "@std/mem"
import "@std/debug"
import "@std/mem"
Error :: enum {
Error :: enum {
expectation_failed
}
SourceLocation :: struct {
file []u8
line usize
column usize
SourceLocation :: struct {
file []u8
line usize
column usize
}
expect proc(condition bool, location SourceLocation) void ! Error {
if !condition {
debug.print("{s}:{d}:{d}: expectation failed\n", {
expect proc(condition bool, location SourceLocation) void ! Error {
if !condition {
debug.print("{s}:{d}:{d}: expectation failed\n", {
location.file,
location.line,
location.column,
})
return .expectation_failed
return .expectation_failed
}
}
expect_equal proc($T type, expected, actual T, location SourceLocation) void ! Error {
match typeinfo!(T) {
.optional: {
if expected |expected_value| {
if actual |actual_value| {
try expect_equal(expected_value, actual_value, location)
expect_equal proc($T type, expected, actual T, location SourceLocation) void ! Error {
match typeinfo!(T) {
.optional: {
if expected |expected_value| {
if actual |actual_value| {
try expect_equal(expected_value, actual_value, location)
return
}
debug.print("{s}:{d}:{d}: expected an optional value, found null\n", {
debug.print("{s}:{d}:{d}: expected an optional value, found null\n", {
location.file,
location.line,
location.column,
})
return .expectation_failed
return .expectation_failed
}
if actual |_| {
debug.print("{s}:{d}:{d}: expected null, found an optional value\n", {
if actual |_| {
debug.print("{s}:{d}:{d}: expected null, found an optional value\n", {
location.file,
location.line,
location.column,
})
return .expectation_failed
return .expectation_failed
}
}
.slice: if !mem.eql(expected, actual) {
debug.print("{s}:{d}:{d}: expected and actual slices differ\n", {
.slice: if !mem.eql(expected, actual) {
debug.print("{s}:{d}:{d}: expected and actual slices differ\n", {
location.file,
location.line,
location.column,
})
return .expectation_failed
return .expectation_failed
}
else: if expected != actual {
debug.print("{s}:{d}:{d}: expected {}, found {}\n", {
else: if expected != actual {
debug.print("{s}:{d}:{d}: expected {}, found {}\n", {
location.file,
location.line,
location.column,
expected,
actual,
})
return .expectation_failed
return .expectation_failed
}
}
}
expect_type proc($Expected, $Actual type, _ Actual, location SourceLocation) void ! Error {
try expect($(Expected == Actual), location)
expect_type proc($Expected, $Actual type, _ Actual, location SourceLocation) void ! Error {
try expect($(Expected == Actual), location)
}
run proc(name []u8, callback *proc() void ! Error) bool {
callback() catch |_| {
debug.print("{s}...[failed]\n", {name,})
return false
run proc(name []u8, callback *proc() void ! Error) bool {
callback() catch |_| {
debug.print("{s}...[failed]\n", {name,})
return false
}
debug.print("{s}...[ok]\n", {name,})
return true
debug.print("{s}...[ok]\n", {name,})
return true
}
summary proc(passed, failed i32) void {
debug.print("{d} passed, {d} failed\n", {passed, failed})
summary proc(passed, failed i32) void {
debug.print("{d} passed, {d} failed\n", {passed, failed})
}