ecdsa cross-tier validation on lumbda-gc and bump-only lumbda blocked
on `case` being unbound. R7RS standard control form — present on
Python (lumbda.py) and C (c/) tiers, but on asm reachable only via
cl_full_prelude's define-macro form (carved into lumbda-full only).
Mirrors commit 865be28 (when/unless via Path B dispatch table).
Path B (special-form dispatch table extension):
- sf_case length-prefixed symbol name
- sym_case_val interned at init_special_forms
- dispatch case in .eval_top alongside .ev_when / .ev_unless
(placed before the .ifdef CL_FULL macro-lookup block so the
dispatch shadow takes precedence over the cl_full_prelude macro
on lumbda-full — no conflict, the macro just becomes dead code)
- .ev_case evaluator: eval key once, push on stack, walk clauses;
each clause's datum list compared by pointer equality (eqv? on
the asm tier — fixnums, symbols, booleans, characters, nil are
all interned/unboxed to unique values). `else` matches uncondi-
tionally. Match → .ev_begin (TCO). No match → .ev_begin_void.
Available on every asm tier (plain `lumbda`, `lumbda-gc`,
`lumbda-full`). Binary size impact:
lumbda 60768 → 61040 (+272, +0.45%)
lumbda-gc 69496 → 69768 (+272, +0.39%)
lumbda-full 72000 → 72264 (+264, +0.37%)
All 158 asm tests still pass. Sanity tests: single-datum, multi-datum,
symbol key (eqv?), else, empty body, no-match, nested case — all
correct on all three tiers.
ecdsa search.lsp now produces byte-identical winner (v3-clifford-only
score 0) across five tiers: Python, C, asm-bump, asm-gc, asm-full.