Skip to content

Commit

Permalink
Merge pull request #247 from jow-/lib-use-sort-r
Browse files Browse the repository at this point in the history
lib: utilize `ucv_array_sort_r()` and `ucv_object_sort_r()`
  • Loading branch information
jow- authored Dec 2, 2024
2 parents b324ad6 + 4e86847 commit c3e468b
Showing 1 changed file with 40 additions and 39 deletions.
79 changes: 40 additions & 39 deletions lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,14 +1403,14 @@ uc_reverse(uc_vm_t *vm, size_t nargs)
}


static struct {
typedef struct {
uc_vm_t *vm;
bool ex;
uc_value_t *fn;
} sort_ctx;
} sort_ctx_t;

static int
default_cmp(uc_value_t *v1, uc_value_t *v2)
default_cmp(uc_value_t *v1, uc_value_t *v2, uc_vm_t *vm)
{
char *s1, *s2;
bool f1, f2;
Expand All @@ -1425,8 +1425,8 @@ default_cmp(uc_value_t *v1, uc_value_t *v2)
}

/* otherwise convert both operands to strings and compare lexically */
s1 = uc_cast_string(sort_ctx.vm, &v1, &f1);
s2 = uc_cast_string(sort_ctx.vm, &v2, &f2);
s1 = uc_cast_string(vm, &v1, &f1);
s2 = uc_cast_string(vm, &v2, &f2);

res = strcmp(s1, s2);

Expand All @@ -1437,31 +1437,30 @@ default_cmp(uc_value_t *v1, uc_value_t *v2)
}

static int
array_sort_fn(const void *k1, const void *k2)
array_sort_fn(uc_value_t *v1, uc_value_t *v2, void *ud)
{
uc_value_t *rv, *null = ucv_int64_new(0);
uc_value_t * const *v1 = k1;
uc_value_t * const *v2 = k2;
sort_ctx_t *ctx = ud;
int res;

if (!sort_ctx.fn)
return default_cmp(*v1, *v2);
if (!ctx->fn)
return default_cmp(v1, v2, ctx->vm);

if (sort_ctx.ex)
if (ctx->ex)
return 0;

uc_vm_ctx_push(sort_ctx.vm);
uc_vm_stack_push(sort_ctx.vm, ucv_get(sort_ctx.fn));
uc_vm_stack_push(sort_ctx.vm, ucv_get(*v1));
uc_vm_stack_push(sort_ctx.vm, ucv_get(*v2));
uc_vm_ctx_push(ctx->vm);
uc_vm_stack_push(ctx->vm, ucv_get(ctx->fn));
uc_vm_stack_push(ctx->vm, ucv_get(v1));
uc_vm_stack_push(ctx->vm, ucv_get(v2));

if (uc_vm_call(sort_ctx.vm, true, 2)) {
sort_ctx.ex = true;
if (uc_vm_call(ctx->vm, true, 2)) {
ctx->ex = true;

return 0;
}

rv = uc_vm_stack_pop(sort_ctx.vm);
rv = uc_vm_stack_pop(ctx->vm);

ucv_compare(0, rv, null, &res);

Expand All @@ -1472,33 +1471,33 @@ array_sort_fn(const void *k1, const void *k2)
}

static int
object_sort_fn(const void *k1, const void *k2)
object_sort_fn(const char *k1, uc_value_t *v1, const char *k2, uc_value_t *v2,
void *ud)
{
uc_value_t *rv, *null = ucv_int64_new(0);
struct lh_entry * const *e1 = k1;
struct lh_entry * const *e2 = k2;
sort_ctx_t *ctx = ud;
int res;

if (!sort_ctx.fn)
return strcmp((char *)lh_entry_k(*e1), (char *)lh_entry_k(*e2));
if (!ctx->fn)
return strcmp(k1, k2);

if (sort_ctx.ex)
if (ctx->ex)
return 0;

uc_vm_ctx_push(sort_ctx.vm);
uc_vm_stack_push(sort_ctx.vm, ucv_get(sort_ctx.fn));
uc_vm_stack_push(sort_ctx.vm, ucv_string_new((char *)lh_entry_k(*e1)));
uc_vm_stack_push(sort_ctx.vm, ucv_string_new((char *)lh_entry_k(*e2)));
uc_vm_stack_push(sort_ctx.vm, ucv_get((uc_value_t *)lh_entry_v(*e1)));
uc_vm_stack_push(sort_ctx.vm, ucv_get((uc_value_t *)lh_entry_v(*e2)));
uc_vm_ctx_push(ctx->vm);
uc_vm_stack_push(ctx->vm, ucv_get(ctx->fn));
uc_vm_stack_push(ctx->vm, ucv_string_new(k1));
uc_vm_stack_push(ctx->vm, ucv_string_new(k2));
uc_vm_stack_push(ctx->vm, ucv_get(v1));
uc_vm_stack_push(ctx->vm, ucv_get(v2));

if (uc_vm_call(sort_ctx.vm, true, 4)) {
sort_ctx.ex = true;
if (uc_vm_call(ctx->vm, true, 4)) {
ctx->ex = true;

return 0;
}

rv = uc_vm_stack_pop(sort_ctx.vm);
rv = uc_vm_stack_pop(ctx->vm);

ucv_compare(0, rv, null, &res);

Expand Down Expand Up @@ -1542,27 +1541,29 @@ uc_sort(uc_vm_t *vm, size_t nargs)
{
uc_value_t *val = uc_fn_arg(0);
uc_value_t *fn = uc_fn_arg(1);
sort_ctx_t ctx = {
.vm = vm,
.fn = fn,
.ex = false
};

if (!assert_mutable(vm, val))
return NULL;

sort_ctx.vm = vm;
sort_ctx.fn = fn;

switch (ucv_type(val)) {
case UC_ARRAY:
ucv_array_sort(val, array_sort_fn);
ucv_array_sort_r(val, array_sort_fn, &ctx);
break;

case UC_OBJECT:
ucv_object_sort(val, object_sort_fn);
ucv_object_sort_r(val, object_sort_fn, &ctx);
break;

default:
return NULL;
}

return sort_ctx.ex ? NULL : ucv_get(val);
return ctx.ex ? NULL : ucv_get(val);
}

/**
Expand Down

0 comments on commit c3e468b

Please sign in to comment.