ref: 3b3bf534ae049f72d15b8b1371f14203d0766979
parent: 8ade82bdfa0fc07740f9000c848f100d8367bf7b
author: Tor Andersson <[email protected]>
date: Tue Jan 28 09:38:17 EST 2014
Array.sort() using insertion sort.
--- a/jsarray.c
+++ b/jsarray.c
@@ -268,8 +268,72 @@
return 1;
}
-// sort
+static int compare(js_State *J, unsigned int x, unsigned int y, int *hasx, int *hasy, int hasfn)
+{
+ const char *sx, *sy;
+ int c;
+ *hasx = js_hasindex(J, 0, x);
+ *hasy = js_hasindex(J, 0, y);
+
+ if (*hasx && *hasy) {
+ int unx = js_isundefined(J, -2);
+ int uny = js_isundefined(J, -1);
+ if (unx && uny) return 0;
+ if (unx) return 1;
+ if (uny) return -1;
+
+ if (hasfn) {
+ js_copy(J, 1); /* copy function */
+ js_pushglobal(J); /* set this object */
+ js_copy(J, -4); /* copy x */
+ js_copy(J, -4); /* copy y */
+ js_call(J, 2);
+ c = js_tonumber(J, -1);
+ js_pop(J, 1);
+ return c;
+ }
+
+ sx = js_tostring(J, -2);
+ sy = js_tostring(J, -1);
+ return strcmp(sx, sy);
+ }
+
+ if (*hasx) return -1;
+ if (*hasy) return 1;
+ return 0;
+}
+
+static int Ap_sort(js_State *J, int argc)
+{
+ unsigned int len, i, k;
+ int hasx, hasy, hasfn;
+
+ len = js_getlength(J, 0);
+
+ hasfn = js_iscallable(J, 1);
+
+ for (i = 1; i < len; ++i) {
+ k = i;
+ while (k > 0 && compare(J, k - 1, k, &hasx, &hasy, hasfn) > 0) {
+ if (hasx && hasy) {
+ js_setindex(J, 0, k - 1);
+ js_setindex(J, 0, k);
+ } else if (hasx) {
+ js_delindex(J, 0, k - 1);
+ js_setindex(J, 0, k);
+ } else if (hasy) {
+ js_setindex(J, 0, k - 1);
+ js_delindex(J, 0, k);
+ }
+ --k;
+ }
+ }
+
+ js_copy(J, 0);
+ return 1;
+}
+
static int Ap_splice(js_State *J, int argc)
{
unsigned int len;
@@ -378,6 +442,7 @@
jsB_propf(J, "reverse", Ap_reverse, 0);
jsB_propf(J, "shift", Ap_shift, 0);
jsB_propf(J, "slice", Ap_slice, 0);
+ jsB_propf(J, "sort", Ap_sort, 1);
jsB_propf(J, "splice", Ap_splice, 0);
jsB_propf(J, "unshift", Ap_unshift, 0);
}