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/compiler.h | 14 ++----- src/bytecode/objects.h | 1 + src/bytecode/vm.h | 99 ++++++++++++++++++++++++++++++------------------- 3 files changed, 65 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index 6f43416..7a25678 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h @@ -80,21 +80,15 @@ compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) { .line = list_start.line, .col = list_start.column, }); + return; } - return; + break; } parse_tree(chunk, vs); n++; - if (n > 1) { - add_code(chunk, op, list_start.line, list_start.column); - } } - error_push((Error){ - .type = ERR_TYPE_COMPILER, - .value = ERR_NOT_ENOUGH_ARGS, - .line = list_start.line, - .col = list_start.column, - }); + emit_constant(chunk, list_start, FIXNUM_VAL(n)); + add_code(chunk, op, list_start.line, list_start.column); } void diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h index a25b0b1..35a954f 100755 --- a/src/bytecode/objects.h +++ b/src/bytecode/objects.h @@ -50,6 +50,7 @@ void display(Object obj); #define TRUE_VAL ((Object){.type = OBJ_TYPE_TRUE}) #define FALSE_VAL ((Object){.type = OBJ_TYPE_FALSE}) #define FIXNUM_VAL(VAL) ((Object){.type = OBJ_TYPE_FIXNUM, .fixnum = VAL}) +#define BOOL_VAL(VAL) ((VAL) ? TRUE_VAL : FALSE_VAL) // Value extraction. #define AS_FIXNUM(VAL) ((VAL).fixnum) 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