js-on-sx: String.prototype extensions + Object/Array builtins
Strings: includes, startsWith, endsWith, trim, trimStart, trimEnd, repeat, padStart, padEnd, toString, valueOf. Object: keys, values, entries, assign, freeze (no-op). Array: isArray, of. All wired into js-global. 17 new unit tests. 357/359 unit (+17), 148/148 slice unchanged.
This commit is contained in:
@@ -885,6 +885,36 @@
|
||||
((>= i (len arr)) acc)
|
||||
(else (js-list-reduce-loop f (f acc (nth arr i)) arr (+ i 1))))))
|
||||
|
||||
(define
|
||||
js-string-repeat
|
||||
(fn
|
||||
(s n acc)
|
||||
(if (<= n 0) acc (js-string-repeat s (- n 1) (str acc s)))))
|
||||
|
||||
(define
|
||||
js-string-pad
|
||||
(fn
|
||||
(s target pad at-start)
|
||||
(let
|
||||
((slen (len s)))
|
||||
(if
|
||||
(or (<= target slen) (= (len pad) 0))
|
||||
s
|
||||
(let
|
||||
((needed (- target slen)))
|
||||
(let
|
||||
((padding (js-string-pad-build pad needed "")))
|
||||
(if at-start (str padding s) (str s padding))))))))
|
||||
|
||||
(define
|
||||
js-string-pad-build
|
||||
(fn
|
||||
(pad needed acc)
|
||||
(cond
|
||||
((<= needed 0) acc)
|
||||
((>= (len acc) needed) (js-string-slice acc 0 needed))
|
||||
(else (js-string-pad-build pad needed (str acc pad))))))
|
||||
|
||||
(define
|
||||
js-string-method
|
||||
(fn
|
||||
@@ -933,6 +963,51 @@
|
||||
((= name "split") (fn (sep) (js-string-split s (js-to-string sep))))
|
||||
((= name "concat")
|
||||
(fn (&rest args) (js-string-concat-loop s args 0)))
|
||||
((= name "includes")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((needle (if (= (len args) 0) "" (js-to-string (nth args 0)))))
|
||||
(>= (js-string-index-of s needle 0) 0))))
|
||||
((= name "startsWith")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((needle (if (= (len args) 0) "" (js-to-string (nth args 0))))
|
||||
(start (if (< (len args) 2) 0 (js-num-to-int (nth args 1)))))
|
||||
(js-string-matches? s needle start 0))))
|
||||
((= name "endsWith")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((needle (if (= (len args) 0) "" (js-to-string (nth args 0)))))
|
||||
(let
|
||||
((end-len (len s)) (n-len (len needle)))
|
||||
(if
|
||||
(> n-len end-len)
|
||||
false
|
||||
(js-string-matches? s needle (- end-len n-len) 0))))))
|
||||
((= name "trim") (fn () (js-trim s)))
|
||||
((= name "trimStart") (fn () (js-trim-left s)))
|
||||
((= name "trimEnd") (fn () (js-trim-right s)))
|
||||
((= name "repeat")
|
||||
(fn (n) (js-string-repeat s (js-num-to-int n) "")))
|
||||
((= name "padStart")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((target (if (= (len args) 0) 0 (js-num-to-int (nth args 0))))
|
||||
(pad (if (< (len args) 2) " " (js-to-string (nth args 1)))))
|
||||
(js-string-pad s target pad true))))
|
||||
((= name "padEnd")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((target (if (= (len args) 0) 0 (js-num-to-int (nth args 0))))
|
||||
(pad (if (< (len args) 2) " " (js-to-string (nth args 1)))))
|
||||
(js-string-pad s target pad false))))
|
||||
((= name "toString") (fn () s))
|
||||
((= name "valueOf") (fn () s))
|
||||
(else js-undefined))))
|
||||
|
||||
(define
|
||||
@@ -1061,6 +1136,17 @@
|
||||
((= key "toLowerCase") (js-string-method obj "toLowerCase"))
|
||||
((= key "split") (js-string-method obj "split"))
|
||||
((= key "concat") (js-string-method obj "concat"))
|
||||
((= key "includes") (js-string-method obj "includes"))
|
||||
((= key "startsWith") (js-string-method obj "startsWith"))
|
||||
((= key "endsWith") (js-string-method obj "endsWith"))
|
||||
((= key "trim") (js-string-method obj "trim"))
|
||||
((= key "trimStart") (js-string-method obj "trimStart"))
|
||||
((= key "trimEnd") (js-string-method obj "trimEnd"))
|
||||
((= key "repeat") (js-string-method obj "repeat"))
|
||||
((= key "padStart") (js-string-method obj "padStart"))
|
||||
((= key "padEnd") (js-string-method obj "padEnd"))
|
||||
((= key "toString") (js-string-method obj "toString"))
|
||||
((= key "valueOf") (js-string-method obj "valueOf"))
|
||||
(else js-undefined)))
|
||||
((= (type-of obj) "dict")
|
||||
(js-dict-get-walk obj (js-to-string key)))
|
||||
@@ -1347,6 +1433,80 @@
|
||||
(dict-set! p "value" reason)
|
||||
(js-promise-flush-callbacks! p))))))
|
||||
|
||||
(define
|
||||
js-object-keys
|
||||
(fn
|
||||
(o)
|
||||
(cond
|
||||
((dict? o)
|
||||
(let
|
||||
((result (list)))
|
||||
(for-each (fn (k) (append! result k)) (keys o))
|
||||
result))
|
||||
(else (list)))))
|
||||
|
||||
(define
|
||||
js-object-values
|
||||
(fn
|
||||
(o)
|
||||
(cond
|
||||
((dict? o)
|
||||
(let
|
||||
((result (list)))
|
||||
(for-each (fn (k) (append! result (get o k))) (keys o))
|
||||
result))
|
||||
(else (list)))))
|
||||
|
||||
(define
|
||||
js-object-entries
|
||||
(fn
|
||||
(o)
|
||||
(cond
|
||||
((dict? o)
|
||||
(let
|
||||
((result (list)))
|
||||
(for-each
|
||||
(fn
|
||||
(k)
|
||||
(let
|
||||
((pair (list)))
|
||||
(append! pair k)
|
||||
(append! pair (get o k))
|
||||
(append! result pair)))
|
||||
(keys o))
|
||||
result))
|
||||
(else (list)))))
|
||||
|
||||
(define
|
||||
js-object-assign
|
||||
(fn
|
||||
(&rest args)
|
||||
(cond
|
||||
((= (len args) 0) (dict))
|
||||
(else
|
||||
(let
|
||||
((target (nth args 0)))
|
||||
(for-each
|
||||
(fn
|
||||
(src)
|
||||
(when
|
||||
(dict? src)
|
||||
(for-each
|
||||
(fn (k) (dict-set! target k (get src k)))
|
||||
(keys src))))
|
||||
(rest args))
|
||||
target)))))
|
||||
|
||||
(define js-object-freeze (fn (o) o))
|
||||
|
||||
(define Object {:entries js-object-entries :values js-object-values :freeze js-object-freeze :assign js-object-assign :keys js-object-keys})
|
||||
|
||||
(define js-array-is-array (fn (v) (list? v)))
|
||||
|
||||
(define js-array-of (fn (&rest args) args))
|
||||
|
||||
(define Array {:isArray js-array-is-array :of js-array-of})
|
||||
|
||||
(define
|
||||
js-promise-flush-callbacks!
|
||||
(fn
|
||||
@@ -1761,4 +1921,4 @@
|
||||
(str "/" (get rx "source") "/" (get rx "flags")))
|
||||
(else js-undefined))))
|
||||
|
||||
(define js-global {:isFinite js-global-is-finite :console console :Number Number :Math Math :NaN 0 :Infinity inf :isNaN js-global-is-nan :undefined js-undefined})
|
||||
(define js-global {:isFinite js-global-is-finite :console console :Number Number :Math Math :Array Array :NaN 0 :Infinity inf :isNaN js-global-is-nan :Object Object :undefined js-undefined})
|
||||
|
||||
Reference in New Issue
Block a user