js-on-sx: 15 new Array.prototype methods (at, flatMap, findLast, reduceRight, toString, toReversed, toSorted, ...)
New read-only methods added: - at(i) — negative-index aware - flatMap(f) — map then flatten one level - findLast(f) / findLastIndex(f) - reduceRight(f, init?) - toString / toLocaleString — join with ',' - keys() / values() / entries() — index/value/pair lists - copyWithin(target, start, end) — in-place via set-nth! - toReversed() / toSorted() — non-mutating variants Mutating methods (unshift, splice) are stubs that return correct lengths but don't mutate — we don't have a pop-first!/clear! primitive to rebuild the list in place. Tracked as a runtime limitation. 10 new unit tests, 479/481 total. Directly targets the 785x ReferenceError in built-ins/Array and the many .toString() crashes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1032,6 +1032,106 @@
|
||||
(< (len args) 2)
|
||||
(- (len arr) 1)
|
||||
(js-num-to-int (nth args 1)))))))
|
||||
((= name "at")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((i (if (empty? args) 0 (js-num-to-int (nth args 0)))))
|
||||
(let
|
||||
((idx (if (< i 0) (+ (len arr) i) i)))
|
||||
(if
|
||||
(or (< idx 0) (>= idx (len arr)))
|
||||
:js-undefined (nth arr idx))))))
|
||||
((= name "unshift") (fn (&rest args) (+ (len arr) (len args))))
|
||||
((= name "splice")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((n (len arr))
|
||||
(start-raw (if (empty? args) 0 (js-num-to-int (nth args 0)))))
|
||||
(let
|
||||
((start (cond ((< start-raw 0) (max 0 (+ n start-raw))) ((> start-raw n) n) (else start-raw))))
|
||||
(let
|
||||
((delete-count (if (< (len args) 2) (- n start) (max 0 (min (- n start) (js-num-to-int (nth args 1)))))))
|
||||
(js-list-slice arr start (+ start delete-count)))))))
|
||||
((= name "flatMap")
|
||||
(fn
|
||||
(f)
|
||||
(let
|
||||
((mapped (js-list-map-loop f arr 0 (list))))
|
||||
(js-list-flat-loop mapped 1 (list)))))
|
||||
((= name "findLast")
|
||||
(fn (f) (js-list-find-last-loop f arr (- (len arr) 1))))
|
||||
((= name "findLastIndex")
|
||||
(fn (f) (js-list-find-last-index-loop f arr (- (len arr) 1))))
|
||||
((= name "reduceRight")
|
||||
(fn
|
||||
(&rest args)
|
||||
(cond
|
||||
((= (len args) 1)
|
||||
(if
|
||||
(= (len arr) 0)
|
||||
(error "Reduce of empty array with no initial value")
|
||||
(js-list-reduce-right-loop
|
||||
(nth args 0)
|
||||
(nth arr (- (len arr) 1))
|
||||
arr
|
||||
(- (len arr) 2))))
|
||||
(else
|
||||
(js-list-reduce-right-loop
|
||||
(nth args 0)
|
||||
(nth args 1)
|
||||
arr
|
||||
(- (len arr) 1))))))
|
||||
((= name "toString") (fn () (js-list-join arr ",")))
|
||||
((= name "toLocaleString") (fn () (js-list-join arr ",")))
|
||||
((= name "keys")
|
||||
(fn
|
||||
()
|
||||
(let
|
||||
((result (list)))
|
||||
(begin (js-list-keys-loop arr 0 result) result))))
|
||||
((= name "values") (fn () (js-list-slice arr 0 (len arr))))
|
||||
((= name "entries")
|
||||
(fn
|
||||
()
|
||||
(let
|
||||
((result (list)))
|
||||
(begin (js-list-entries-loop arr 0 result) result))))
|
||||
((= name "copyWithin")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((n (len arr))
|
||||
(target-raw
|
||||
(if (empty? args) 0 (js-num-to-int (nth args 0))))
|
||||
(start-raw
|
||||
(if (< (len args) 2) 0 (js-num-to-int (nth args 1))))
|
||||
(end-raw
|
||||
(if
|
||||
(< (len args) 3)
|
||||
(len arr)
|
||||
(js-num-to-int (nth args 2)))))
|
||||
(let
|
||||
((target (cond ((< target-raw 0) (max 0 (+ n target-raw))) (else (min n target-raw))))
|
||||
(start
|
||||
(cond
|
||||
((< start-raw 0) (max 0 (+ n start-raw)))
|
||||
(else (min n start-raw))))
|
||||
(end
|
||||
(cond
|
||||
((< end-raw 0) (max 0 (+ n end-raw)))
|
||||
(else (min n end-raw)))))
|
||||
(begin (js-list-copy-within! arr target start end) arr)))))
|
||||
((= name "toReversed")
|
||||
(fn () (js-list-reverse-loop arr (- (len arr) 1) (list))))
|
||||
((= name "toSorted")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((cmp (if (empty? args) nil (nth args 0)))
|
||||
(copy (js-list-slice arr 0 (len arr))))
|
||||
(begin (js-list-sort! copy cmp) copy))))
|
||||
(else js-undefined))))
|
||||
|
||||
(define pop-last! (fn (lst) nil))
|
||||
@@ -1267,6 +1367,73 @@
|
||||
(append! acc (nth arr i))
|
||||
(js-list-reverse-loop arr (- i 1) acc))))))
|
||||
|
||||
(define
|
||||
js-list-find-last-loop
|
||||
(fn
|
||||
(f arr i)
|
||||
(cond
|
||||
((< i 0) :js-undefined)
|
||||
((js-to-boolean (f (nth arr i))) (nth arr i))
|
||||
(else (js-list-find-last-loop f arr (- i 1))))))
|
||||
|
||||
(define
|
||||
js-list-find-last-index-loop
|
||||
(fn
|
||||
(f arr i)
|
||||
(cond
|
||||
((< i 0) -1)
|
||||
((js-to-boolean (f (nth arr i))) i)
|
||||
(else (js-list-find-last-index-loop f arr (- i 1))))))
|
||||
|
||||
(define
|
||||
js-list-reduce-right-loop
|
||||
(fn
|
||||
(f acc arr i)
|
||||
(if
|
||||
(< i 0)
|
||||
acc
|
||||
(js-list-reduce-right-loop f (f acc (nth arr i)) arr (- i 1)))))
|
||||
|
||||
(define
|
||||
js-list-keys-loop
|
||||
(fn
|
||||
(arr i result)
|
||||
(if
|
||||
(>= i (len arr))
|
||||
result
|
||||
(begin (append! result i) (js-list-keys-loop arr (+ i 1) result)))))
|
||||
|
||||
(define
|
||||
js-list-entries-loop
|
||||
(fn
|
||||
(arr i result)
|
||||
(if
|
||||
(>= i (len arr))
|
||||
result
|
||||
(begin
|
||||
(append! result (list i (nth arr i)))
|
||||
(js-list-entries-loop arr (+ i 1) result)))))
|
||||
|
||||
(define
|
||||
js-list-copy-within!
|
||||
(fn
|
||||
(arr target start end)
|
||||
(let
|
||||
((snap (js-list-slice arr start end)))
|
||||
(js-list-copy-within-loop! arr target snap 0))))
|
||||
|
||||
(define
|
||||
js-list-copy-within-loop!
|
||||
(fn
|
||||
(arr target snap i)
|
||||
(cond
|
||||
((>= i (len snap)) arr)
|
||||
((>= (+ target i) (len arr)) arr)
|
||||
(else
|
||||
(begin
|
||||
(set-nth! arr (+ target i) (nth snap i))
|
||||
(js-list-copy-within-loop! arr target snap (+ i 1)))))))
|
||||
|
||||
(define
|
||||
js-string-repeat
|
||||
(fn
|
||||
@@ -1577,6 +1744,21 @@
|
||||
((= key "fill") (js-array-method obj "fill"))
|
||||
((= key "sort") (js-array-method obj "sort"))
|
||||
((= key "lastIndexOf") (js-array-method obj "lastIndexOf"))
|
||||
((= key "at") (js-array-method obj "at"))
|
||||
((= key "unshift") (js-array-method obj "unshift"))
|
||||
((= key "splice") (js-array-method obj "splice"))
|
||||
((= key "flatMap") (js-array-method obj "flatMap"))
|
||||
((= key "findLast") (js-array-method obj "findLast"))
|
||||
((= key "findLastIndex") (js-array-method obj "findLastIndex"))
|
||||
((= key "reduceRight") (js-array-method obj "reduceRight"))
|
||||
((= key "toString") (js-array-method obj "toString"))
|
||||
((= key "toLocaleString") (js-array-method obj "toLocaleString"))
|
||||
((= key "keys") (js-array-method obj "keys"))
|
||||
((= key "values") (js-array-method obj "values"))
|
||||
((= key "entries") (js-array-method obj "entries"))
|
||||
((= key "copyWithin") (js-array-method obj "copyWithin"))
|
||||
((= key "toReversed") (js-array-method obj "toReversed"))
|
||||
((= key "toSorted") (js-array-method obj "toSorted"))
|
||||
(else js-undefined)))
|
||||
((= (type-of obj) "string")
|
||||
(cond
|
||||
|
||||
Reference in New Issue
Block a user