diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index 4ccb6b3b..7b62670c 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -2284,11 +2284,50 @@ (>= (js-list-index-of arr (nth args 0) 0) 0)))) - ((= name "find") (fn (f) (js-list-find-loop f arr 0))) + ((= name "find") + (fn (&rest args) + (let + ((f (if (empty? args) :js-undefined (nth args 0))) + (this-arg + (cond + ((< (len args) 2) js-global-this) + ((js-undefined? (nth args 1)) js-global-this) + ((= (nth args 1) nil) js-global-this) + (else (nth args 1))))) + (js-list-find-loop f arr this-arg 0)))) ((= name "findIndex") - (fn (f) (js-list-find-index-loop f arr 0))) - ((= name "some") (fn (f) (js-list-some-loop f arr 0))) - ((= name "every") (fn (f) (js-list-every-loop f arr 0))) + (fn (&rest args) + (let + ((f (if (empty? args) :js-undefined (nth args 0))) + (this-arg + (cond + ((< (len args) 2) js-global-this) + ((js-undefined? (nth args 1)) js-global-this) + ((= (nth args 1) nil) js-global-this) + (else (nth args 1))))) + (js-list-find-index-loop f arr this-arg 0)))) + ((= name "some") + (fn (&rest args) + (let + ((f (if (empty? args) :js-undefined (nth args 0))) + (this-arg + (cond + ((< (len args) 2) js-global-this) + ((js-undefined? (nth args 1)) js-global-this) + ((= (nth args 1) nil) js-global-this) + (else (nth args 1))))) + (js-list-some-loop f arr this-arg 0)))) + ((= name "every") + (fn (&rest args) + (let + ((f (if (empty? args) :js-undefined (nth args 0))) + (this-arg + (cond + ((< (len args) 2) js-global-this) + ((js-undefined? (nth args 1)) js-global-this) + ((= (nth args 1) nil) js-global-this) + (else (nth args 1))))) + (js-list-every-loop f arr this-arg 0)))) ((= name "reverse") (fn () (js-list-reverse-loop arr (- (len arr) 1) (list)))) ((= name "flat") @@ -2590,29 +2629,32 @@ (define js-list-find-loop (fn - (f arr i) + (f arr this-arg i) (cond ((>= i (len arr)) js-undefined) - ((js-to-boolean (f (nth arr i))) (nth arr i)) - (else (js-list-find-loop f arr (+ i 1)))))) + ((js-to-boolean (js-call-with-this this-arg f (list (nth arr i) i arr))) + (nth arr i)) + (else (js-list-find-loop f arr this-arg (+ i 1)))))) (define js-list-find-index-loop (fn - (f arr i) + (f arr this-arg i) (cond ((>= i (len arr)) -1) - ((js-to-boolean (f (nth arr i))) i) - (else (js-list-find-index-loop f arr (+ i 1)))))) + ((js-to-boolean (js-call-with-this this-arg f (list (nth arr i) i arr))) + i) + (else (js-list-find-index-loop f arr this-arg (+ i 1)))))) (define js-list-some-loop (fn - (f arr i) + (f arr this-arg i) (cond ((>= i (len arr)) false) - ((js-to-boolean (f (nth arr i))) true) - (else (js-list-some-loop f arr (+ i 1)))))) + ((js-to-boolean (js-call-with-this this-arg f (list (nth arr i) i arr))) + true) + (else (js-list-some-loop f arr this-arg (+ i 1)))))) (define js-list-flat-loop @@ -2688,11 +2730,12 @@ (define js-list-every-loop (fn - (f arr i) + (f arr this-arg i) (cond ((>= i (len arr)) true) - ((not (js-to-boolean (f (nth arr i)))) false) - (else (js-list-every-loop f arr (+ i 1)))))) + ((not (js-to-boolean (js-call-with-this this-arg f (list (nth arr i) i arr)))) + false) + (else (js-list-every-loop f arr this-arg (+ i 1)))))) (define js-list-reverse-loop diff --git a/plans/js-on-sx.md b/plans/js-on-sx.md index 370dd6d6..2f66349d 100644 --- a/plans/js-on-sx.md +++ b/plans/js-on-sx.md @@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green. Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta. +- 2026-05-09 — **`Array.prototype.find`/`findIndex`/`some`/`every` honour `thisArg` and pass `(value, index, array)`.** Same shape as the previous `forEach`/`map`/`filter` fix — these were calling `(f x)` directly. Updated each prototype method to extract optional `thisArg` (defaulting to globalThis when null/undefined) and route through `js-call-with-this` with the full `(value, index, array)` triple. Updated `js-list-find-loop` / `js-list-find-index-loop` / `js-list-some-loop` / `js-list-every-loop` to match. Result: built-ins/Array/prototype/find 5/30 → 6/30. Modest delta this round (most remaining failures need deeper Array semantics — sparse arrays, ToLength on `length`, etc.). Object 30/30, Map 18/30 unchanged. conformance.sh: 148/148. + - 2026-05-09 — **`Array.prototype.forEach`/`map`/`filter` honour `thisArg` and pass `(value, index, array)` to callback.** Was calling the callback with just `(value)` from a bare `(f x)` and ignoring the optional second `thisArg` parameter. Per spec, the callback receives `(value, index, array)` and `this` is `thisArg ?? globalThis` in non-strict. Updated the prototype methods to take `&rest args`, extract `thisArg` (defaulting to globalThis when null/undefined), and route through `js-call-with-this` with the full triple. Updated `js-list-foreach-loop` / `js-list-map-loop` / `js-list-filter-loop` accordingly. Result: built-ins/Array/prototype/forEach 2/30 → 9/30, filter 5/30 → 10/30. Array 18/30, Object 30/30, Map 18/30 unchanged. conformance.sh: 148/148. - 2026-05-09 — **`Map.prototype.forEach` / `Set.prototype.forEach` honour `thisArg` and pass `(value, key, collection)` to callback.** Was hardcoding `js-undefined` as the callback receiver and only passing `(value, key)`. Per spec, the callback receives `(value, key, collection)` and `this` is `thisArg ?? globalThis` in non-strict. Updated `js-map-do-foreach` / `js-set-do-foreach` to accept an optional `thisArg`, defaulting to `globalThis` when null/undefined; the prototype methods now route the second positional arg through. Result: built-ins/Map/prototype 11/30 → 13/30, built-ins/Set/prototype +similar. Map 18/30 holds. conformance.sh: 148/148.