zpy

A lisp like language written in hare
Log | Files | Refs

commit 00d693f55da3cb0edfdc2ebf25e0dd25a270217a
parent 4efce2e290a7d42d0a4eb1c3b50460af1e3cc8e6
Author: thing1 <thing1@seacrossedlovers.xyz>
Date:   Wed, 13 May 2026 10:08:35 +0100

added allocators, although lots of memory bugs

im not even using them anymore, but ill keep it around i guess

Diffstat:
Mallocate/alloc.ha | 20+++++++++++++++-----
Aallocate/arena/+test.ha | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aallocate/arena/arena.ha | 37+++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/allocate/alloc.ha b/allocate/alloc.ha @@ -1,12 +1,22 @@ -export type createfn = fn(_: allocator, _: *opaque) (*opaque | nomem); -export type destroyfn = fn(_: allocator, _: *opaque) void; +export type createfn = fn(_: *allocator, _: *opaque, _: size) (*opaque | nomem); +export type destroyfn = fn(_: *allocator, _: *opaque) void; +export type finishfn = fn(_: *allocator) void; export type vtable = struct { create: *createfn, - destroy: *destroyfn + destroy: *destroyfn, + finish: *finishfn }; export type allocator = *vtable; -export fn create(al: allocator, obj: *opaque) (*opaque | nomem) = al.create(al, obj); -export fn destroy(al: allocator, obj: *opaque) (*opaque | nomem) = al.destroy(al, obj); +export fn create(al: *allocator, obj: *opaque, s: size) (*opaque | nomem) = al.create(al, obj, s); +export fn destroy(al: *allocator, obj: *opaque) void = al.destroy(al, obj); +export fn finish(al: *allocator) void = al.finish(al); + +export fn copy(dst: *[*]u8, src: *[*]u8, s: size) void = { + for (let i = 0z; i < s; i += 1) + dst[i] = src[i]; +}; + +export fn destroy_nothing(al: *allocator, obj: *opaque) void = return; diff --git a/allocate/arena/+test.ha b/allocate/arena/+test.ha @@ -0,0 +1,67 @@ +use allocate; + +@test +fn SimpleAlloc() void = { + let al = &new(100)!; + defer allocate::finish(al); + + let ptr = allocate::create(al, &42: *int, size(int))!: *int; + + assert(*ptr == 42); +}; + +@test +fn TooSmallAlloc() void = { + let al = &new(5)!; + defer allocate::finish(al); + + let ptr = allocate::create(al, &[42, 43, 44]: *[]int, size(int) * 3); + + assert(ptr is nomem); +}; + +@test +fn ExactAlloc() void = { + let al = &new(size(int) * 3)!; + defer allocate::finish(al); + + let ptr = allocate::create(al, &[42, 43, 44]: *[]int, size(int) * 3): *[*]int; + + assert(ptr[0] == 42); + assert(ptr[1] == 43); + assert(ptr[2] == 44); +}; + +@test +fn OneSmallAlloc() void = { + let al = &new((size(int) * 3) - 1)!; + defer allocate::finish(al); + + let ptr = allocate::create(al, &[42, 43, 44]: *[]int, size(int) * 3); + + assert(ptr is nomem); +}; + +@test +fn OneBigAlloc() void = { + let al = &new((size(int) * 3) + 1)!; + defer allocate::finish(al); + + let ptr = allocate::create(al, &[42, 43, 44]: *[]int, size(int) * 3): *[*]int; + + assert(ptr[0] == 42); + assert(ptr[1] == 43); + assert(ptr[2] == 44); +}; + +@test +fn MultiAlloc() void = { + let al = &new(100)!; + defer allocate::finish(al); + + let ptr = allocate::create(al, &42: *int, size(int)): *int; + let ptr2 = allocate::create(al, &123: *int, size(int)): *int; + + assert(*ptr == 42); + assert(*ptr2 == 123); +}; diff --git a/allocate/arena/arena.ha b/allocate/arena/arena.ha @@ -0,0 +1,37 @@ +use allocate; + +export type arena = struct { + al: allocate::allocator, + heap: *[*]u8, + s: size, + pos: size +}; + +const vtable = allocate::vtable { + create = &create, + destroy = &allocate::destroy_nothing, + finish = &finish +}; + +fn create(al: *allocate::allocator, obj: *opaque, s: size) (*opaque | nomem) = { + let arena = al: *arena; + if (arena.pos + s > arena.s) return nomem; + + allocate::copy(&arena.heap[arena.pos]: *[*]u8, obj: *[*]u8, s); + defer arena.pos += s; + return &arena.heap[arena.pos]: *opaque; +}; + +fn finish(al: *allocate::allocator) void = { + let arena = al: *arena; + free(arena.heap); +}; + +export fn new(s: size) (arena | nomem) = { + return arena{ + al = &vtable, + heap: *[*]u8 = alloc([0...], s)?: *[*]u8, + s = s, + pos = 0z + }; +};