Browse Source
Bounded -multiple occurrence ranges now PARTICIPATE in positional allocation
for leaders and values instead of being post-loop enforcement only.
Previously greedy collection overran a bounded max unless a type screen
happened to stop it - untyped {3 3} followed by a -multiple tail collected 4
words and occurrencecount then reported the overrun the allocation itself
created (and typed {3 3} with four consecutive ints failed identically) -
and a later REQUIRED ranged argument was starved to a single reserved
clause.
Three cooperating sites:
(a) get_dict_can_assign_value caps a satisfied -multiple argument at its
bounded max: the word is yielded (no-consume) so the caller's retreat
advances to the next argument - one proc serving both the leaders and
values loops. The yield carries a G-082 rejection record of new kind
'occurrence', and both loops' overflow selection sites render it as the
pointed occurrence-limit report with the G-053 occurrencecount errorcode
(count = the attempted occurrence) instead of the generic toomanyarguments,
so genuine over-supply keeps its pointed class - now describing an overflow
the allocator refused rather than one it created.
(b) Reservations are min-occurrence aware: the allocator's tail_needs and
the derived valmin floor (leader/value split + option-scan reservation)
reserve min-occurrences x min-clause-length for a required ranged argument
- a following required -multiple {3 3} reserves 3 clauses, {2 2} pair
clauses reserve 4 words - so earlier greed cannot starve it. An explicit
'@values -min' still overrides the derived floor; legacy boolean -multiple
(no MULTIPLE_RANGES entry) reserves exactly as before.
(c) The greedy leader scan caps a bounded -multiple last leader at max
occurrences (via the leader_posn_names_assigned counter), so remaining
words flow to the opts/values sections. (The split is a separate pre-loop
scan - capping only the loops left over-provided leader words raising
toomanyarguments.)
First occurrences are never capped (resolve guarantees range max >= 1);
{0 1} at-most-once scalars are unaffected (no collection); bounded-variable
ranges take greedy-up-to-max deterministically; legacy boolean greed is
byte-unchanged (pinned). define -help -multiple documents the allocation
semantics.
multipleranges.test gains 7 allocation pins: untyped/typed {3 3} cap incl
the cap-beats-type-screen four-ints case, greedy-up-to-max {1 2},
required-range and pair-clause reservations, the leaders-side scan cap +
split floor, the pointed over-supply report, and a legacy-greed-unchanged
guard. src/tests/modules/AGENTS.md index updated.
Project 0.61.0 -> 0.62.0 + CHANGELOG (allocation behaviour is user-visible
shell parsing). punk::args 0.24.0 -> 0.25.0.
Suites: punk/args 408/0; modules tree 1320 pass / 11 constraint-skipped /
0 fail (zig-built tclsh90s 9.0.5); testbody_lint clean; make.tcl
projectversion consistency OK.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
6 changed files with 186 additions and 9 deletions
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue