From 835025ec37142c3a147da3e9911db18f9b4ce6ae Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 23 Apr 2026 21:28:50 +0000 Subject: [PATCH] js-on-sx: Array.prototype flat + fill; fix indexOf start arg flat: walk with depth, recursive when element is list and depth>0. fill(value, start?, end?): in-place mutation, returns self. indexOf: honor second arg as start position. 396/398 unit (+5), 148/148 slice unchanged. --- lib/js/runtime.sx | 53 ++++++++++++++++++++++++++++++++++++++++++++++- lib/js/test.sh | 19 +++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index 0d9c3957..2b50b02a 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -775,7 +775,13 @@ ((= name "indexOf") (fn (&rest args) - (if (= (len args) 0) -1 (js-list-index-of arr (nth args 0) 0)))) + (if + (= (len args) 0) + -1 + (js-list-index-of + arr + (nth args 0) + (if (< (len args) 2) 0 (js-num-to-int (nth args 1))))))) ((= name "join") (fn (&rest args) @@ -810,6 +816,25 @@ ((= name "every") (fn (f) (js-list-every-loop f arr 0))) ((= name "reverse") (fn () (js-list-reverse-loop arr (- (len arr) 1) (list)))) + ((= name "flat") + (fn + (&rest args) + (let + ((depth (if (= (len args) 0) 1 (js-num-to-int (nth args 0))))) + (js-list-flat-loop arr depth (list))))) + ((= name "fill") + (fn + (&rest args) + (let + ((v (if (= (len args) 0) js-undefined (nth args 0))) + (s (if (< (len args) 2) 0 (js-num-to-int (nth args 1)))) + (e + (if + (< (len args) 3) + (len arr) + (js-num-to-int (nth args 2))))) + (js-list-fill-loop arr v s e) + arr))) (else js-undefined)))) (define pop-last! (fn (lst) nil)) @@ -960,6 +985,30 @@ ((js-to-boolean (f (nth arr i))) true) (else (js-list-some-loop f arr (+ i 1)))))) +(define + js-list-flat-loop + (fn + (arr depth acc) + (for-each + (fn + (x) + (if + (and (list? x) (> depth 0)) + (js-list-flat-loop x (- depth 1) acc) + (append! acc x))) + arr) + acc)) + +(define + js-list-fill-loop + (fn + (arr v s e) + (cond + ((>= s e) nil) + ((>= s (len arr)) nil) + (else + (begin (js-list-set! arr s v) (js-list-fill-loop arr v (+ s 1) e)))))) + (define js-list-every-loop (fn @@ -1219,6 +1268,8 @@ ((= key "some") (js-array-method obj "some")) ((= key "every") (js-array-method obj "every")) ((= key "reverse") (js-array-method obj "reverse")) + ((= key "flat") (js-array-method obj "flat")) + ((= key "fill") (js-array-method obj "fill")) (else js-undefined))) ((= (type-of obj) "string") (cond diff --git a/lib/js/test.sh b/lib/js/test.sh index ed680169..8202e458 100755 --- a/lib/js/test.sh +++ b/lib/js/test.sh @@ -1015,6 +1015,18 @@ cat > "$TMPFILE" << 'EPOCHS' (epoch 2009) (eval "(js-eval \"JSON.parse('{\\\"a\\\":1}').a\")") +;; ── Phase 11.array2: flat + fill + indexOf start ─────────────── +(epoch 2100) +(eval "(js-eval \"[1,[2,3],4].flat().length\")") +(epoch 2101) +(eval "(js-eval \"[1,[2,[3]]].flat(2).length\")") +(epoch 2102) +(eval "(js-eval \"[1,2,3].fill(0).join(',')\")") +(epoch 2103) +(eval "(js-eval \"[1,2,3,4].fill(0, 1, 3).join(',')\")") +(epoch 2104) +(eval "(js-eval \"[1,2,1,2].indexOf(2, 2)\")") + EPOCHS @@ -1559,6 +1571,13 @@ check 2007 "parse string" '"hello"' check 2008 "parse array length" '3' check 2009 "parse object.a" '1' +# ── Phase 11.array2 ──────────────────────────────────────────── +check 2100 "flat() depth 1" '4' +check 2101 "flat(2)" '3' +check 2102 "fill(0)" '"0,0,0"' +check 2103 "fill(0,1,3)" '"1,0,0,4"' +check 2104 "indexOf with start" '3' + TOTAL=$((PASS + FAIL)) if [ $FAIL -eq 0 ]; then echo "✓ $PASS/$TOTAL JS-on-SX tests passed"