From b7aaa1897ba855cc0aba372a7773c057ec7479d2 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Sun, 23 Jan 2022 15:11:48 -0800 Subject: [PATCH] Implement A_SORT_MEM Sorts an array of structs by a given member. --- include/vm/page.h | 1 + src/page.c | 22 ++++++++++++++++++++++ src/vm.c | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/include/vm/page.h b/include/vm/page.h index c88c5ed..3ff167d 100644 --- a/include/vm/page.h +++ b/include/vm/page.h @@ -126,6 +126,7 @@ struct page *array_popback(struct page *dst); struct page *array_erase(struct page *page, int i, bool *success); struct page *array_insert(struct page *page, int i, union vm_value v, enum ain_data_type data_type, int struct_type); void array_sort(struct page *page, int compare_fno); +void array_sort_mem(struct page *page, int member_no); int array_find(struct page *page, int start, int end, union vm_value v, int compare_fno); void array_reverse(struct page *page); diff --git a/src/page.c b/src/page.c index 703bad6..a40f228 100644 --- a/src/page.c +++ b/src/page.c @@ -542,6 +542,28 @@ void array_sort(struct page *page, int compare_fno) qsort(page->values, page->nr_vars, sizeof(union vm_value), array_compare); } +static int current_sort_member; + +static int array_compare_member(const void *_a, const void *_b) +{ + union vm_value a_slot = *((union vm_value*)_a); + union vm_value b_slot = *((union vm_value*)_b); + struct page *a = heap_get_page(a_slot.i); + struct page *b = heap_get_page(b_slot.i); + return a->values[current_sort_member].i - b->values[current_sort_member].i; +} + +void array_sort_mem(struct page *page, int member_no) +{ + if (!page) + return; + if (page->type != ARRAY_PAGE || array_type(page->a_type) != AIN_STRUCT) + VM_ERROR("A_SORT_MEM called on something other than an array of structs"); + + current_sort_member = member_no; + qsort(page->values, page->nr_vars, sizeof(union vm_value), array_compare_member); +} + int array_find(struct page *page, int start, int end, union vm_value v, int compare_fno) { if (!page) diff --git a/src/vm.c b/src/vm.c index 1e0ce9a..bc7b25b 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2042,6 +2042,12 @@ static enum opcode execute_instruction(enum opcode opcode) stack_push(i < get_argument(1) || i >= get_argument(2)); break; } + case A_SORT_MEM: { + int mno = stack_pop().i; + int array = stack_pop_var()->i; + array_sort_mem(heap[array].page, mno); + break; + } //case DG_ADD: case DG_SET: { int fun = stack_pop().i;