From fcf015508c98d16dd34d87e5df0538b44178143d Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 26 Oct 2021 15:19:25 +0200 Subject: Checking n_args at runtime for OP_CALL --- src/bytecode/vm.h | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'src/bytecode/vm.h') diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 2bc5c8a..ed54046 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h @@ -60,37 +60,29 @@ vm_reset(VM *vm) { } // Helper macros for a more clear VM switch. -#define WRONG_ARG_ERR() \ +#define RUNTIME_ERROR(ERR) \ error_push((Error){ \ .type = ERR_TYPE_RUNTIME, \ - .value = ERR_WRONG_ARG_TYPE, \ + .value = (ERR), \ .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \ .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \ }); \ return -#define SYMBOL_NOT_FOUND_ERR() \ - error_push((Error){ \ - .type = ERR_TYPE_RUNTIME, \ - .value = ERR_SYMBOL_NOT_FOUND, \ - .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \ - .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \ - }) - #define FIXNUM_ARITHMETIC_OP(OP) \ do { \ 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(); \ + RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \ return; \ } \ ssize_t acc = AS_FIXNUM(obj); \ while (n > 1) { \ obj = array_peek(vm->stack, n - 2); \ if (!IS_FIXNUM(obj)) { \ - WRONG_ARG_ERR(); \ + RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \ return; \ } \ ssize_t current = AS_FIXNUM(obj); \ @@ -107,7 +99,7 @@ vm_reset(VM *vm) { size_t stack_size = array_size(vm->stack) - n; \ Object obj = array_peek(vm->stack, n - 1); \ if (!IS_FIXNUM(obj)) { \ - WRONG_ARG_ERR(); \ + RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \ return; \ } \ ssize_t prev = AS_FIXNUM(obj); \ @@ -115,7 +107,7 @@ vm_reset(VM *vm) { while (n > 1) { \ obj = array_peek(vm->stack, n - 2); \ if (!IS_FIXNUM(obj)) { \ - WRONG_ARG_ERR(); \ + RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \ return; \ } \ ssize_t current = AS_FIXNUM(obj); \ @@ -184,7 +176,7 @@ vm_interpret(VM *vm) { Object name = array_pop(vm->stack); Object *prev = ht_lookup(vm->globals, name); if (prev == NULL) { - SYMBOL_NOT_FOUND_ERR(); + RUNTIME_ERROR(ERR_SYMBOL_NOT_FOUND); return; } ht_insert(vm->globals, name, value); @@ -193,7 +185,7 @@ vm_interpret(VM *vm) { Object name = array_pop(vm->stack); Object *value = ht_lookup(vm->globals, name); if (value == NULL) { - SYMBOL_NOT_FOUND_ERR(); + RUNTIME_ERROR(ERR_SYMBOL_NOT_FOUND); return; } array_push(vm->stack, *value); @@ -235,7 +227,7 @@ vm_interpret(VM *vm) { case OP_PRINT: { Object obj = array_pop(vm->stack); if (!IS_STRING(obj)) { - WRONG_ARG_ERR(); + RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); } StringView scanner = (StringView) { .start = obj.text, @@ -260,7 +252,20 @@ vm_interpret(VM *vm) { printf("\n"); } break; case OP_CALL: { + ssize_t n_args = AS_FIXNUM(array_pop(vm->stack)); Object proc = array_pop(vm->stack); + + // Check the number of arguments is correct. + // NOTE: This is probably better handled at compilation, but for + // now this is simpler to implement. + ssize_t n_params = array_size(proc.chunk->params); + if (n_args < n_params) { + RUNTIME_ERROR(ERR_NOT_ENOUGH_ARGS); + } else if (n_args > n_params) { + RUNTIME_ERROR(ERR_TOO_MANY_ARGS); + } + + // DEBUG:... // disassemble_chunk(proc.chunk); // Tail-call optimization. @@ -299,13 +304,7 @@ vm_interpret(VM *vm) { array_head(vm->stack)->size = 0; } break; default: { - error_push((Error){ - .type = ERR_TYPE_RUNTIME, - .value = ERR_NOT_IMPLEMENTED, - .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, - .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, - }); - return; + RUNTIME_ERROR(ERR_NOT_IMPLEMENTED); } break; } } -- cgit v1.2.1