Implement A_FIND instruction

This one is not supported by the SDK compiler, so no automated tests.
This commit is contained in:
Nunuhara Cabbage
2019-11-30 15:47:06 -08:00
parent b11319eb66
commit 91af527def
3 changed files with 36 additions and 0 deletions
+27
View File
@@ -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;
}
+1
View File
@@ -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 */
+8
View File
@@ -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;