From c841ece42e75fe545d35b86299aa9e69cb751ac6 Mon Sep 17 00:00:00 2001 From: Judah Caruso Date: Thu, 19 Feb 2026 11:08:34 -0700 Subject: [PATCH] fixes + macros --- do.ps1 | 8 +++++++- src/arena.c | 19 ++++++++++--------- src/base.c | 16 +++++++++------- src/main.c | 6 +++++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/do.ps1 b/do.ps1 index bb520f7..0b57625 100755 --- a/do.ps1 +++ b/do.ps1 @@ -145,6 +145,7 @@ switch ($command) { Write-Host (":: Compiling natively" + $(if ($release) { " (release mode)" } else { "" })); Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; } {($_ -eq "build-cross") -or ($_ -eq "bc")} { @@ -161,6 +162,7 @@ switch ($command) { Write-Host (":: Cross-compiling for $target" + $(if ($release) { " (release mode)" } else { "" })); Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; } {($_ -eq "run") -or ($_ -eq "r")} { @@ -170,8 +172,12 @@ switch ($command) { Write-Host (":: Compiling natively" + $(if ($release) { " (release mode)" } else { "" })); Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; - Invoke-Expression $binary | Write-Host; + + if ($LASTEXITCODE -eq 0) { + Invoke-Expression $binary | Write-Host; + } } {($_ -eq "list-targets") -or ($_ -eq "lt")} { # zig target doesn't actually output json... diff --git a/src/arena.c b/src/arena.c index 84e636f..b11991a 100644 --- a/src/arena.c +++ b/src/arena.c @@ -4,7 +4,7 @@ typedef enum { arena__alloc, arena__reset, arena__save, arena__restore, arena__release } arena__action; -typedef void* (^Arena)(arena__action, ureg, ureg, void*, const char*, sreg); +typedef closure(void*, arena__action, ureg, ureg, void*, const char*, sreg) Arena; #define arena_new(A, T) cast(T*, A(arena__alloc, sizeof(T), alignof(T), 0, __FILE__, __LINE__)) #define arena_make(A, C, T) cast(T*, A(arena__alloc, sizeof(T) * (C), alignof(T), 0, __FILE__, __LINE__)) @@ -13,22 +13,23 @@ typedef void* (^Arena)(arena__action, ureg, ureg, void*, const char*, sreg); #define arena_save(A, SP) A(arena__save, 0, 0, (SP), __FILE__, __LINE__) #define arena_restore(A, SP) A(arena__restore, 0, 0, (SP), __FILE__, __LINE__) -// just a nice macro to make these easier to write -#define func(a1, a2, a3, a4, a5, a6) ^void* (arena__action a1, ureg a2, ureg a3, void* a4, const char* a5, sreg a6) +// tiny macro to make arenas easier to declare +#define $(a1, a2, a3, a4, a5, a6) ^void* (arena__action a1, ureg a2, ureg a3, void* a4, const char* a5, sreg a6) static Arena Static(u8* data, ureg count) { memset(data, 0, count); capture ureg offset = 0; - return closure(func(action, size, align, savepoint, _2, _3) { + return persist($(action, size, align, savepoint, _2, _3) { switch (action) { default: { } break; case arena__alloc: { offset = (offset + align - 1) & ~(align - 1); - if (offset + size > count) return 0; + if (offset + size > count) + { return 0; } void* ptr = data + offset; offset += size; @@ -59,7 +60,7 @@ static Arena Linear(ureg max_memory) { void* ptr = malloc(max_memory); Arena backing = Static(ptr, max_memory); - return closure(func(action, size, align, savepoint, file, line) { + return persist($(action, size, align, savepoint, file, line) { if (action == arena__release) { free(ptr); return 0; @@ -71,7 +72,7 @@ Linear(ureg max_memory) { static Arena Logger(Arena arena) { - return closure(func(action, size, align, savepoint, file, line) { + return persist($(action, size, align, savepoint, file, line) { char* action_str = "unknown"; switch (action) { case arena__alloc: action_str = "alloc"; break; @@ -91,7 +92,7 @@ Region(Arena arena) { capture ureg savepoint = 0; arena_save(arena, &savepoint); - return closure(func(action, size, align, _, file, line) { + return persist($(action, size, align, _, file, line) { if (action == arena__reset || action == arena__restore) { return arena(arena__restore, size, align, &savepoint, file, line); } @@ -100,4 +101,4 @@ Region(Arena arena) { }); } -#undef func +#undef $ diff --git a/src/base.c b/src/base.c index 642f6b6..2b5b1b6 100644 --- a/src/base.c +++ b/src/base.c @@ -27,19 +27,21 @@ typedef sptr sreg; #define ptrcast(to_type, from_type, expr) _Generic(expr, from_type: (to_type)(uintptr_t)(expr)) #define bitcast(to_type, from_type, expr) (((union { from_type from; to_type to; }){_Generic(expr, from_type: expr)}).to) +#define procedure(ret_type, ...) typeof(ret_type(__VA_ARGS__))* +#define closure(ret_type, ...) typeof(ret_type(__VA_ARGS__))^ #include -#define capture __block -#define closure Block_copy +#define capture __block // allows a variable to be mutably captured by a closure (will be moved to the heap if needed) +#define persist Block_copy // moves a closure to the heap (reference counted) so it can persist outside of its local stack frame +#define unpersist Block_release // frees a closure (or decrements its reference count) -typedef void (^__defer__block)(void); - -static inline void __defer__exec(__defer__block *blk) { (*blk)(); } +typedef closure(void, void) __scope_exit; +static inline void __scope_exit_run(__scope_exit *blk) { (*blk)(); } #define __concat__2(a, b) a##b #define __concat(a, b) __concat__2(a, b) #define scope_exit \ - __attribute__((cleanup(__defer__exec), unused)) \ - __defer__block __concat(_defer_, __LINE__) = ^ + __attribute__((cleanup(__scope_exit_run), unused)) \ + __scope_exit __concat(_defer_, __LINE__) = ^void(void) diff --git a/src/main.c b/src/main.c index 0ca1e3e..733ce6c 100644 --- a/src/main.c +++ b/src/main.c @@ -25,6 +25,10 @@ sg_pass_action pass_action; static void init(void) { + scope_exit { + printf("leaving init..."); + }; + sg_setup(&(sg_desc){ .environment = sglue_environment(), .logger.func = slog_func, @@ -50,7 +54,7 @@ init(void) { // c23 tests capture auto x = 0; - auto inc = closure(^{ + auto inc = persist(^{ x += 1; });