W14: pin K09/K11/K39 landed W5 special-form fixes (test-only)
Three dc7aa709 fixes shipped without pinning tests:
- K09: R7RS longhand (unquote-splicing X) now splices (was silent zero-splice)
- K11: guard re-raise sentinel gensym'd — a user value shaped like
(list '__guard-reraise__ X) is data, not a forged re-raise
- K39: (do ((fn (x) x) 5) 99) -> 99, not a misparsed Scheme do-loop
Add suites gate-K09-longhand-unquote-splicing, gate-K11-guard-reraise-forgeable,
gate-K39-do-iife-head to spec/tests/test-gate-pins.sx with exact reprs from
plans/sx-review/core.md. 261 passed / 0 failed under OCaml run_tests.
Test-only: no semantics edits, no push.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ Pin each confirmed-and-fixed finding with a minimal repro. Add suites to
|
||||
|
||||
- [x] K18 [W7] — `expt` overflow now float-promotes (no 63-bit wrap)
|
||||
- [x] K20 [W7] — `contains?` now supports dict key membership
|
||||
- [ ] K09/K11/K39 [W5] — landed special-form fixes, pin each
|
||||
- [x] K09/K11/K39 [W5] — longhand `unquote-splicing`, guard sentinel gensym, `do` IIFE-head
|
||||
- [ ] K49 [W8] — render depth/cycle guard (infinite recursive component)
|
||||
- [ ] crit-2 [W1] — signal-return frame key (verify the pin is non-vacuous)
|
||||
- [ ] C1/C1b [W3] — HTTP-mode concurrency fixes, pin
|
||||
@@ -77,6 +77,16 @@ Pin each confirmed-and-fixed finding with a minimal repro. Add suites to
|
||||
|
||||
## Progress log (newest first)
|
||||
|
||||
- 2026-07-03 — **K09/K11/K39 W5 special-form pins (item A.3)**. Three suites
|
||||
added to `spec/tests/test-gate-pins.sx`: `gate-K09-longhand-unquote-splicing`
|
||||
(R7RS longhand `(unquote-splicing X)` now splices, incl. empty-list case;
|
||||
shorthand still works), `gate-K11-guard-reraise-forgeable` (a body/clause
|
||||
value shaped like `(list '__guard-reraise__ X)` is returned as data, not
|
||||
misread as a re-raise — sentinel is now gensym'd), `gate-K39-do-iife-head`
|
||||
(`(do ((fn (x) x) 5) 99)` → 99, not a misparsed do-loop — exact core.md
|
||||
repro). Gotchas hit and fixed: quasiquoted bare idents are *symbols* not
|
||||
strings, and `assert=` compares with `=` (not `equal?`, which returns false
|
||||
on these spliced lists). 261 passed / 0 failed under OCaml run_tests. Test-only.
|
||||
- 2026-07-03 — **K20 contains?-dict pin (item A.2)**. Mapped K-codes by
|
||||
core.md severity order (K17 append!, K18 expt, K19 harness-drift, K20
|
||||
contains?-dict). Added suite `gate-K20-contains-dict` to
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
;;
|
||||
;; TEST-ONLY: no semantics edits. If a pin fails, the fix regressed — do NOT
|
||||
;; relax the assertion; investigate the evaluator/primitive change.
|
||||
;; NB: assert= uses `=` (not `equal?`); compare lists with `=`.
|
||||
;; ==========================================================================
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
@@ -56,3 +57,65 @@
|
||||
(deftest
|
||||
"contains? still works on string substrings"
|
||||
(assert (contains? "hello" "ell"))))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; K09 [W5, high] R7RS longhand (unquote-splicing X) silently no-spliced —
|
||||
;; only shorthand ,@/`splice-unquote` was recognized, so the longhand
|
||||
;; serialized literally (zero-splice). Fixed: aliased to splice-unquote.
|
||||
;; Repro (core.md).
|
||||
;; --------------------------------------------------------------------------
|
||||
(defsuite
|
||||
"gate-K09-longhand-unquote-splicing"
|
||||
(deftest
|
||||
"longhand unquote-splicing splices a list"
|
||||
(assert=
|
||||
(quasiquote
|
||||
(1
|
||||
(unquote-splicing (list 2 3))
|
||||
4))
|
||||
(list 1 2 3 4)))
|
||||
(deftest
|
||||
"longhand unquote-splicing of an empty list contributes nothing"
|
||||
(assert=
|
||||
(quasiquote (0 (unquote-splicing (list)) 9))
|
||||
(list 0 9)))
|
||||
(deftest
|
||||
"shorthand splice-unquote still works"
|
||||
(assert=
|
||||
(quasiquote (a (splice-unquote (list 2 3)) z))
|
||||
(list (quote a) 2 3 (quote z)))))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; K11 [W5, high] guard re-raise sentinel was a plain forgeable symbol — a
|
||||
;; body/clause legitimately returning (list '__guard-reraise__ X) was
|
||||
;; misread as a re-raise of X. Fixed: sentinel gensym'd per execution, so a
|
||||
;; user value with that head is returned as data. Repro (core.md).
|
||||
;; --------------------------------------------------------------------------
|
||||
(defsuite
|
||||
"gate-K11-guard-reraise-forgeable"
|
||||
(deftest
|
||||
"body value shaped like the sentinel is returned as data"
|
||||
(assert=
|
||||
(guard (e (true "caught")) (list (quote __guard-reraise__) "hi"))
|
||||
(list (quote __guard-reraise__) "hi")))
|
||||
(deftest
|
||||
"clause returning the forged sentinel is not re-raised"
|
||||
(assert=
|
||||
(guard
|
||||
(e (true (list (quote __guard-reraise__) "forged")))
|
||||
(error "boom"))
|
||||
(list (quote __guard-reraise__) "forged"))))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; K39 [W5, med] `do` misparsed a first form whose head is a list (an IIFE)
|
||||
;; as a Scheme do-loop binding spec. Repro (core.md): (do ((fn (x) x) 5) 99)
|
||||
;; threw "first: expected list, got 5"; expected 99. Fixed: `do` is begin.
|
||||
;; --------------------------------------------------------------------------
|
||||
(defsuite
|
||||
"gate-K39-do-iife-head"
|
||||
(deftest
|
||||
"do with an IIFE first form returns the last form (not a do-loop)"
|
||||
(assert= (do ((fn (x) x) 5) 99) 99))
|
||||
(deftest
|
||||
"do with a single IIFE form returns its value"
|
||||
(assert= (do ((fn () 42))) 42)))
|
||||
|
||||
Reference in New Issue
Block a user