js-on-sx: callable Number/String/Boolean/Array + Array.sort
Builtin constructors now have :__callable__ slot. js-call-plain
and js-function? detect dicts with __callable__ and dispatch
through it. Number('42')===42, String(true)==='true', Boolean(0)
===false, Array(3) builds length-3 list.
Array.prototype.sort(comparator?): bubble sort via js-list-sort-
outer!/-inner!. Default lex order, custom comparator supported.
Wide scoreboard committed: 259/5354 (4.8%) from earlier runtime.
438/440 unit (+11), 148/148 slice unchanged.
This commit is contained in:
@@ -232,6 +232,8 @@
|
||||
(cond
|
||||
((js-undefined? fn-val)
|
||||
(error "TypeError: undefined is not a function"))
|
||||
((and (dict? fn-val) (contains? (keys fn-val) "__callable__"))
|
||||
(js-call-with-this :js-undefined (get fn-val "__callable__") args))
|
||||
(else (js-call-with-this :js-undefined fn-val args)))))
|
||||
|
||||
(define
|
||||
@@ -396,7 +398,11 @@
|
||||
(v)
|
||||
(let
|
||||
((t (type-of v)))
|
||||
(or (= t "lambda") (= t "function") (= t "component")))))
|
||||
(or
|
||||
(= t "lambda")
|
||||
(= t "function")
|
||||
(= t "component")
|
||||
(and (= t "dict") (contains? (keys v) "__callable__"))))))
|
||||
|
||||
;; Bitwise + logical-not
|
||||
(define __js_proto_table__ (dict))
|
||||
@@ -835,6 +841,13 @@
|
||||
(js-num-to-int (nth args 2)))))
|
||||
(js-list-fill-loop arr v s e)
|
||||
arr)))
|
||||
((= name "sort")
|
||||
(fn
|
||||
(&rest args)
|
||||
(let
|
||||
((cmp (if (= (len args) 0) nil (nth args 0))))
|
||||
(js-list-sort! arr cmp)
|
||||
arr)))
|
||||
(else js-undefined))))
|
||||
|
||||
(define pop-last! (fn (lst) nil))
|
||||
@@ -1009,6 +1022,38 @@
|
||||
(else
|
||||
(begin (js-list-set! arr s v) (js-list-fill-loop arr v (+ s 1) e))))))
|
||||
|
||||
(define
|
||||
js-list-sort!
|
||||
(fn (arr cmp) (let ((n (len arr))) (js-list-sort-outer! arr cmp 0 n))))
|
||||
|
||||
(define
|
||||
js-list-sort-outer!
|
||||
(fn
|
||||
(arr cmp i n)
|
||||
(cond
|
||||
((>= i n) nil)
|
||||
(else
|
||||
(begin
|
||||
(js-list-sort-inner! arr cmp 0 (- n i 1))
|
||||
(js-list-sort-outer! arr cmp (+ i 1) n))))))
|
||||
|
||||
(define
|
||||
js-list-sort-inner!
|
||||
(fn
|
||||
(arr cmp i end)
|
||||
(cond
|
||||
((>= i end) nil)
|
||||
(else
|
||||
(begin
|
||||
(let
|
||||
((a (nth arr i)) (b (nth arr (+ i 1))))
|
||||
(let
|
||||
((result (if (= cmp nil) (if (js-str-lt (js-to-string b) (js-to-string a)) 1 -1) (js-to-number (cmp a b)))))
|
||||
(when
|
||||
(> result 0)
|
||||
(begin (js-list-set! arr i b) (js-list-set! arr (+ i 1) a)))))
|
||||
(js-list-sort-inner! arr cmp (+ i 1) end))))))
|
||||
|
||||
(define
|
||||
js-list-every-loop
|
||||
(fn
|
||||
@@ -1337,6 +1382,7 @@
|
||||
((= key "reverse") (js-array-method obj "reverse"))
|
||||
((= key "flat") (js-array-method obj "flat"))
|
||||
((= key "fill") (js-array-method obj "fill"))
|
||||
((= key "sort") (js-array-method obj "sort"))
|
||||
(else js-undefined)))
|
||||
((= (type-of obj) "string")
|
||||
(cond
|
||||
@@ -1566,7 +1612,7 @@
|
||||
|
||||
(define js-global-is-nan (fn (v) (js-number-is-nan (js-to-number v))))
|
||||
|
||||
(define Number {:isFinite js-number-is-finite :MAX_SAFE_INTEGER 9007199254740991 :EPSILON 2.22045e-16 :MAX_VALUE 0 :POSITIVE_INFINITY inf :isInteger js-number-is-integer :isNaN js-number-is-nan :isSafeInteger js-number-is-safe-integer :NEGATIVE_INFINITY -inf :NaN 0 :MIN_VALUE 4.94066e-324 :MIN_SAFE_INTEGER -9007199254740991})
|
||||
(define Number {:isFinite js-number-is-finite :MAX_SAFE_INTEGER 9007199254740991 :EPSILON 2.22045e-16 :MAX_VALUE 0 :POSITIVE_INFINITY inf :__callable__ js-to-number :isInteger js-number-is-integer :isNaN js-number-is-nan :isSafeInteger js-number-is-safe-integer :NEGATIVE_INFINITY -inf :NaN 0 :MIN_VALUE 4.94066e-324 :MIN_SAFE_INTEGER -9007199254740991})
|
||||
|
||||
(define isFinite js-global-is-finite)
|
||||
|
||||
@@ -1815,7 +1861,7 @@
|
||||
src)
|
||||
result)))))))
|
||||
|
||||
(define Array {:isArray js-array-is-array :of js-array-of :from js-array-from})
|
||||
(define Array {:__callable__ (fn (&rest args) (cond ((= (len args) 0) (list)) ((and (= (len args) 1) (number? (nth args 0))) (js-make-list-of-length (js-num-to-int (nth args 0)) js-undefined)) (else args))) :isArray js-array-is-array :of js-array-of :from js-array-from})
|
||||
|
||||
(define
|
||||
js-string-from-char-code
|
||||
@@ -1833,7 +1879,9 @@
|
||||
(+ i 1)
|
||||
(str acc (js-code-to-char (js-num-to-int (nth args i))))))))
|
||||
|
||||
(define String {:fromCharCode js-string-from-char-code})
|
||||
(define String {:fromCharCode js-string-from-char-code :__callable__ (fn (&rest args) (if (= (len args) 0) "" (js-to-string (nth args 0))))})
|
||||
|
||||
(define Boolean {:__callable__ (fn (&rest args) (if (= (len args) 0) false (js-to-boolean (nth args 0))))})
|
||||
|
||||
(define
|
||||
parseInt
|
||||
@@ -2508,4 +2556,4 @@
|
||||
(str "/" (get rx "source") "/" (get rx "flags")))
|
||||
(else js-undefined))))
|
||||
|
||||
(define js-global {:isFinite js-global-is-finite :console console :Number Number :parseFloat parseFloat :Math Math :Array Array :String String :NaN 0 :Infinity inf :isNaN js-global-is-nan :Object Object :parseInt parseInt :JSON JSON :undefined js-undefined})
|
||||
(define js-global {:isFinite js-global-is-finite :console console :Number Number :parseFloat parseFloat :Math Math :Array Array :Boolean Boolean :String String :NaN 0 :Infinity inf :isNaN js-global-is-nan :Object Object :parseInt parseInt :JSON JSON :undefined js-undefined})
|
||||
|
||||
Reference in New Issue
Block a user