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