FORMAT with ~A/~S/~D/~F/~%/~&/~T/~P/~{...~}/~^; cl-fmt-loop,
cl-fmt-find-close, cl-fmt-iterate, cl-fmt-a/cl-fmt-s helpers.
Fix substr(start,length) semantics throughout: SUBSEQ end formula
corrected to (- end start), cl-fmt-loop char extraction fixed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
defmacro/macrolet/symbol-macrolet/macroexpand, gensym/gentemp, full
LOOP macro (loop.sx) with all clause types. Phase 2 dynamic variables:
cl-apply-dyn, cl-letstar-bind, cl-mark-special!/cl-special? for
defvar/defparameter specials with let-based dynamic rebinding.
27 macro+LOOP tests; 182 eval tests (8 new dynamic var tests).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cl-debugger-hook: mutable global (fn (c hook) result); cl-invoke-debugger
calls it with infinite-recursion guard (sets hook nil during call).
cl-error now routes unhandled errors through cl-invoke-debugger instead of
bare host error — allows the hook to invoke a restart and resume.
cl-break-on-signals: when set to a type name, cl-signal fires the debugger
hook before walking handlers if the condition matches.
cl-invoke-restart-interactively: calls the restart fn with no args (no
terminal protocol — equivalent to (invoke-restart name)).
4 new tests in conditions.sx covering all three; Phase 3 fully complete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cl-debugger-hook global (nil = default), cl-invoke-debugger walks the hook,
cl-error-with-debugger routes unhandled errors through the hook, and
make-policy-debugger builds a hook from a (fn (condition restarts) name)
policy function. Tests: hook receives condition, policy selects use-zero/abort
restarts, compute-restarts visible inside hook, handler wins before hook fires,
infinite-recursion guard. Wired into test.sh program suite runner.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
restart-demo.sx: safe-divide with division-by-zero condition, use-zero
and retry restarts. Demonstrates handler-bind invoking a restart to
resume computation with a corrected value.
parse-recover.sx: token parser signalling parse-error on non-integer
tokens, skip-token and use-zero restarts. Demonstrates recovery-via-
restart and handler-case abort patterns.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
define-condition with 15-type ANSI hierarchy (condition/error/warning/
simple-error/simple-warning/type-error/arithmetic-error/division-by-zero/
cell-error/unbound-variable/undefined-function/program-error/storage-condition).
cl-condition-of-type? walks the hierarchy; cl-make-condition builds tagged
dicts {:cl-type "cl-condition" :class name :slots {...}}. cl-signal-obj
walks cl-handler-stack for non-unwinding dispatch. cl-handler-case and
cl-restart-case use call/cc escape continuations for unwinding. All stacks
are mutable SX globals (the built-in handler-bind/restart-case only accept
literal AST specs — not computed lists). Key fix: cl-condition-of-type?
captures cl-condition-classes at define-time via let-closure to avoid
free-variable failure through env_merge parent chain.
55 tests in lib/common-lisp/tests/conditions.sx, wired into test.sh.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lib/js/stdlib.sx (36 forms):
- Bitwise ops (js-bitand/bitor/bitxor/lshift/rshift/urshift/bitnot) use
truncate instead of js-num-to-int (which calls integer /0 and crashes).
- Map class: dict-backed list-of-pairs with linear-scan find, mutable via
dict-set!; js-map-new/get/set!/has/delete!/clear/keys/vals/entries/for-each.
- Set class: backed by SX make-set primitive; set-member?/set-add!/set-remove!
all take (set item) argument order — fixed from (item set) which threw.
- RegExp: callable lambda wrapping js-regex-new (not a dict, so directly callable).
- Wires Map/Set/RegExp into js-global.
lib/js/test.sh: epochs 6000-6032 (25 tests) — all pass.
Result: 492/585 tests pass (was 466/560 before this phase).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gensym_counter ref + gensym/string->symbol/symbol->string/intern/symbol-interned?
primitives in sx_primitives.ml. Fix ListRef case in seq_to_list on both
sx_ref.ml and sx_primitives.ml. 19 new tests in test-gensym.sx.
OCaml 4450/1080, JS 2205/2497, zero regressions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- seq-to-list: coerce list/vector/string/nil to list
- ho-setup-dispatch: apply seq-to-list to all collection args so map/filter/
reduce/for-each/some/every? work over vectors and strings natively
- sequence->list, sequence->vector, sequence-length, sequence-ref,
sequence-append: full polymorphic sequence helpers
- in-range: list-returning range generator (eager, works with all HO forms)
- Restore 3 accidentally-deleted make-cek-state/make-cek-value/make-cek-suspended
- Fix 8 shorthand define forms (transpiler requires long form)
- Add vector->list/list->vector to transpiler js-renames + platform aliases
- JS: 2137 passing (+28 vs HEAD baseline)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>