From b271ce1d9098c9057fccdca6eba6b0ee0a5245a2 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 23 Oct 2021 19:47:50 +0200 Subject: Change relevant OPs to use list operations --- src/bytecode/vm.h | 99 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 39 deletions(-) (limited to 'src/bytecode/vm.h') diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index c94e22b..b3dd8c3 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h @@ -41,41 +41,62 @@ vm_reset(VM *vm) { } // Helper macros for a more clear VM switch. -#define FIXNUM_BINARY_OP(OP) \ +#define WRONG_ARG_ERR() \ + error_push((Error){ \ + .type = ERR_TYPE_RUNTIME, \ + .value = ERR_WRONG_ARG_TYPE, \ + .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ + .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ + }) + +#define FIXNUM_ARITHMETIC_OP(OP) \ do { \ - Object a = array_pop(vm->stack); \ - Object b = array_pop(vm->stack); \ - if (!IS_FIXNUM(a) || !IS_FIXNUM(b)) { \ - error_push((Error){ \ - .type = ERR_TYPE_RUNTIME, \ - .value = ERR_WRONG_ARG_TYPE, \ - .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ - .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ - }); \ + ssize_t n = AS_FIXNUM(array_pop(vm->stack)); \ + size_t stack_size = array_size(vm->stack) - n; \ + Object obj = array_peek(vm->stack, n - 1); \ + if (!IS_FIXNUM(obj)) { \ + WRONG_ARG_ERR(); \ return; \ } \ - ssize_t x = AS_FIXNUM(a); \ - ssize_t y = AS_FIXNUM(b); \ - array_push(vm->stack, FIXNUM_VAL(y OP x)); \ + ssize_t acc = AS_FIXNUM(obj); \ + while (n > 1) { \ + obj = array_peek(vm->stack, n - 2); \ + if (!IS_FIXNUM(obj)) { \ + WRONG_ARG_ERR(); \ + return; \ + } \ + ssize_t current = AS_FIXNUM(obj); \ + acc = acc OP current; \ + n--; \ + } \ + array_head(vm->stack)->size = stack_size; \ + array_push(vm->stack, FIXNUM_VAL(acc)); \ } while (false) -#define FIXNUM_CMP_OP(OP) \ +#define FIXNUM_COMPARE_OP(OP) \ do { \ - Object a = array_pop(vm->stack); \ - Object b = array_pop(vm->stack); \ - if (!IS_FIXNUM(a) || !IS_FIXNUM(b)) { \ - error_push((Error){ \ - .type = ERR_TYPE_RUNTIME, \ - .value = ERR_WRONG_ARG_TYPE, \ - .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ - .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ - }); \ + ssize_t n = AS_FIXNUM(array_pop(vm->stack)); \ + size_t stack_size = array_size(vm->stack) - n; \ + Object obj = array_peek(vm->stack, n - 1); \ + if (!IS_FIXNUM(obj)) { \ + WRONG_ARG_ERR(); \ return; \ } \ - ssize_t x = AS_FIXNUM(a); \ - ssize_t y = AS_FIXNUM(b); \ - Object result = y OP x ? TRUE_VAL : FALSE_VAL; \ - array_push(vm->stack, result); \ + ssize_t prev = AS_FIXNUM(obj); \ + bool ret = true; \ + while (n > 1) { \ + obj = array_peek(vm->stack, n - 2); \ + if (!IS_FIXNUM(obj)) { \ + WRONG_ARG_ERR(); \ + return; \ + } \ + ssize_t current = AS_FIXNUM(obj); \ + ret = ret && (prev OP current); \ + prev = current; \ + n--; \ + } \ + array_head(vm->stack)->size = stack_size; \ + array_push(vm->stack, BOOL_VAL(ret)); \ } while (false) #define LOGIC_OP(OP) \ @@ -121,11 +142,11 @@ vm_interpret(VM *vm, Chunk *chunk) { Object obj = vm->chunk->constants[constant]; array_push(vm->stack, obj); } break; - case OP_SUM: { FIXNUM_BINARY_OP(+); } break; - case OP_SUB: { FIXNUM_BINARY_OP(-); } break; - case OP_MUL: { FIXNUM_BINARY_OP(*); } break; - case OP_DIV: { FIXNUM_BINARY_OP(/); } break; - case OP_MOD: { FIXNUM_BINARY_OP(%); } break; + case OP_SUM: { FIXNUM_ARITHMETIC_OP(+); } break; + case OP_SUB: { FIXNUM_ARITHMETIC_OP(-); } break; + case OP_MUL: { FIXNUM_ARITHMETIC_OP(*); } break; + case OP_DIV: { FIXNUM_ARITHMETIC_OP(/); } break; + case OP_MOD: { FIXNUM_ARITHMETIC_OP(%); } break; case OP_NOT: { Object prev = array_pop(vm->stack); Object new = IS_TRUE(prev) ? FALSE_VAL : TRUE_VAL; @@ -133,11 +154,11 @@ vm_interpret(VM *vm, Chunk *chunk) { } break; case OP_AND: { LOGIC_OP(&&); } break; case OP_OR: { LOGIC_OP(||); } break; - case OP_EQUAL: { FIXNUM_CMP_OP(==); } break; - case OP_LESS: { FIXNUM_CMP_OP(<); } break; - case OP_GREATER: { FIXNUM_CMP_OP(>); } break; - case OP_LESS_EQUAL: { FIXNUM_CMP_OP(<=); } break; - case OP_GREATER_EQUAL: { FIXNUM_CMP_OP(>=); } break; + case OP_EQUAL: { FIXNUM_COMPARE_OP(==); } break; + case OP_LESS: { FIXNUM_COMPARE_OP(<); } break; + case OP_GREATER: { FIXNUM_COMPARE_OP(>); } break; + case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; + case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; case OP_RETURN: { display(array_pop(vm->stack)); printf("\n"); @@ -163,8 +184,8 @@ vm_interpret(VM *vm, Chunk *chunk) { }); } -#undef FIXNUM_BINARY_OP -#undef FIXNUM_CMP_OP +#undef FIXNUM_ARITHMETIC_OP +#undef FIXNUM_COMPARE_OP #undef LOGIC_OP #endif // BDL_VM_H -- cgit v1.2.1