diff --git a/page.c b/page.c index 3c4da81..e16b35f 100644 --- a/page.c +++ b/page.c @@ -443,3 +443,30 @@ void array_sort(struct page *page, int compare_fno) current_sort_function = compare_fno; qsort(page->values, sizeof(union vm_value), page->nr_vars, array_compare); } + +int array_find(struct page *page, int start, int end, union vm_value v, int compare_fno) +{ + if (!page) + return -1; + + start = max(start, 0); + end = min(end, page->nr_vars); + + // if no compare function given, compare integer values + if (!compare_fno) { + for (int i = start; i < end; i++) { + if (page->values[i].i == v.i) + return i; + } + return -1; + } + + for (int i = start; i < end; i++) { + stack_push(v); + stack_push(page->values[i]); + vm_call(compare_fno, -1); + if (stack_pop().i) + return i; + } + return -1; +} diff --git a/page.h b/page.h index e898d6d..34e4d71 100644 --- a/page.h +++ b/page.h @@ -98,5 +98,6 @@ void array_popback(struct page **dst); bool array_erase(struct page **page, int i); void array_insert(struct page **_page, int i, union vm_value v, int data_type, int struct_type); void array_sort(struct page *page, int compare_fno); +int array_find(struct page *page, int start, int end, union vm_value v, int compare_fno); #endif /* SYSTEM4_PAGE_H */ diff --git a/vm.c b/vm.c index 6a38016..ef225d8 100644 --- a/vm.c +++ b/vm.c @@ -1158,6 +1158,14 @@ static void execute_instruction(enum opcode opcode) slot = stack_pop_var()->i; array_sort(heap[slot].page, a); break; + case A_FIND: { + int fno = stack_pop().i; + union vm_value v = stack_pop(); + int end = stack_pop().i; + int start = stack_pop().i; + int array = stack_pop_var()->i; + stack_push(array_find(heap[array].page, start, end, v, fno)); + } // -- NOOPs --- case FUNC: break;