lib/regex: finish() ports the Hare frees verbatim (#27 landed)

ref/hare/regex/regex.ha:96-102 body restored word-for-word now that
the free() builtin is a documented no-op: each free evaluates its
operand and reclaims nothing (ww is a no-free runtime, rt/alloc.s:30).
Drops the fold-1 empty-body stub and its held-back note.
This commit is contained in:
2026-06-04 06:07:27 +09:00
parent 9732061a7e
commit 60ad118da0

View File

@@ -4,13 +4,12 @@
// other metacharacter arm, exec / find / replace are DEFERRED to // other metacharacter arm, exec / find / replace are DEFERRED to
// later folds. // later folds.
// //
// Two fold-1 constructs are held back behind filed compiler/fidelity // One fold-1 construct is held back behind a filed compiler/fidelity
// gaps (see the charclass_map and finish() sites below): // gap (see the charclass_map site below):
// - charclass_map (regex.ha:74-87) — a module-level const slice of // - charclass_map (regex.ha:74-87) — a module-level const slice of
// (str, *fn(rune) bool) tuples. Blocked on the array-literal→slice // (str, *fn(rune) bool) tuples. Blocked on the array-literal→slice
// element-coercion checker gap (#25; type.c:402-404 #258 borrow // element-coercion checker gap (#25; type.c:402-404 #258 borrow
// uses exact type_eq, no element decay). // uses exact type_eq, no element decay).
// - finish() (regex.ha:96-102) — frees; ww is a no-free runtime (#27).
package regex; package regex;
import strings; import strings;
@@ -92,15 +91,18 @@ export type regex = struct {
// Frees resources associated with a [[regex]]. // Frees resources associated with a [[regex]].
// //
// ref/hare/regex/regex.ha:96-102 frees re.insts / each charset / // ref/hare/regex/regex.ha:96-102, verbatim. The free() builtin is a
// re.charsets. ww is a no-free runtime (rt/alloc.s:30 — rt_free is a // documented no-op (#27 landed): ww is a no-free runtime (rt/alloc.s:30
// no-op; the bump allocator can't reclaim, process-exit does), so the // the bump allocator can't reclaim, process-exit does), so each free
// faithful ww body drops the frees, matching how the port drops every // below evaluates its operand and reclaims nothing. Kept verbatim for
// Hare free(). Kept for API parity with the Hare surface. Temporary // API + source parity with the Hare surface.
// empty body: #27 makes the free() builtin compile to a documented export fn finish(re: *regex) void = {
// no-op, after which this ports the Hare frees VERBATIM (the no-op free(re.insts);
// builtin reclaims nothing, same end state). for (let charset .. re.charsets) {
export fn finish(re: *regex) void = { }; free(charset);
};
free(re.charsets);
};
// Compiles a regular expression string into a [[regex]]. // Compiles a regular expression string into a [[regex]].
// //
@@ -114,8 +116,9 @@ export fn finish(re: *regex) void = { };
// was_prev_rune_pipe / group_level / capture_idx (ha:253-256). // was_prev_rune_pipe / group_level / capture_idx (ha:253-256).
// //
// Hare's `defer if (!ok) free(...)` cleanup (ha:231-237) is omitted: // Hare's `defer if (!ok) free(...)` cleanup (ha:231-237) is omitted:
// ww has no `defer if` (cf lib/strings/strings.ww:85) and is a no-free // ww has no `defer if` (cf lib/strings/strings.ww:85), and the free()
// runtime (#27)the port drops every Hare free(). // builtin is a no-op anyway (#27 — ww is a no-free runtime), so the
// cleanup would reclaim nothing.
export fn compile(expr: str) (regex | error | nomem) = { export fn compile(expr: str) (regex | error | nomem) = {
// Hare `let insts: []inst = [];` — a bare ww slice declaration // Hare `let insts: []inst = [];` — a bare ww slice declaration
// zeroes the header (cgen.c:9836 no-rhs multi-word composite // zeroes the header (cgen.c:9836 no-rhs multi-word composite