aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode/vm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-xsrc/bytecode/vm.h47
1 files changed, 23 insertions, 24 deletions
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) {
60} 60}
61 61
62// Helper macros for a more clear VM switch. 62// Helper macros for a more clear VM switch.
63#define WRONG_ARG_ERR() \ 63#define RUNTIME_ERROR(ERR) \
64 error_push((Error){ \ 64 error_push((Error){ \
65 .type = ERR_TYPE_RUNTIME, \ 65 .type = ERR_TYPE_RUNTIME, \
66 .value = ERR_WRONG_ARG_TYPE, \ 66 .value = (ERR), \
67 .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \ 67 .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \
68 .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \ 68 .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \
69 }); \ 69 }); \
70 return 70 return
71 71
72#define SYMBOL_NOT_FOUND_ERR() \
73 error_push((Error){ \
74 .type = ERR_TYPE_RUNTIME, \
75 .value = ERR_SYMBOL_NOT_FOUND, \
76 .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \
77 .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \
78 })
79
80#define FIXNUM_ARITHMETIC_OP(OP) \ 72#define FIXNUM_ARITHMETIC_OP(OP) \
81 do { \ 73 do { \
82 ssize_t n = AS_FIXNUM(array_pop(vm->stack)); \ 74 ssize_t n = AS_FIXNUM(array_pop(vm->stack)); \
83 size_t stack_size = array_size(vm->stack) - n; \ 75 size_t stack_size = array_size(vm->stack) - n; \
84 Object obj = array_peek(vm->stack, n - 1); \ 76 Object obj = array_peek(vm->stack, n - 1); \
85 if (!IS_FIXNUM(obj)) { \ 77 if (!IS_FIXNUM(obj)) { \
86 WRONG_ARG_ERR(); \ 78 RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \
87 return; \ 79 return; \
88 } \ 80 } \
89 ssize_t acc = AS_FIXNUM(obj); \ 81 ssize_t acc = AS_FIXNUM(obj); \
90 while (n > 1) { \ 82 while (n > 1) { \
91 obj = array_peek(vm->stack, n - 2); \ 83 obj = array_peek(vm->stack, n - 2); \
92 if (!IS_FIXNUM(obj)) { \ 84 if (!IS_FIXNUM(obj)) { \
93 WRONG_ARG_ERR(); \ 85 RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \
94 return; \ 86 return; \
95 } \ 87 } \
96 ssize_t current = AS_FIXNUM(obj); \ 88 ssize_t current = AS_FIXNUM(obj); \
@@ -107,7 +99,7 @@ vm_reset(VM *vm) {
107 size_t stack_size = array_size(vm->stack) - n; \ 99 size_t stack_size = array_size(vm->stack) - n; \
108 Object obj = array_peek(vm->stack, n - 1); \ 100 Object obj = array_peek(vm->stack, n - 1); \
109 if (!IS_FIXNUM(obj)) { \ 101 if (!IS_FIXNUM(obj)) { \
110 WRONG_ARG_ERR(); \ 102 RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \
111 return; \ 103 return; \
112 } \ 104 } \
113 ssize_t prev = AS_FIXNUM(obj); \ 105 ssize_t prev = AS_FIXNUM(obj); \
@@ -115,7 +107,7 @@ vm_reset(VM *vm) {
115 while (n > 1) { \ 107 while (n > 1) { \
116 obj = array_peek(vm->stack, n - 2); \ 108 obj = array_peek(vm->stack, n - 2); \
117 if (!IS_FIXNUM(obj)) { \ 109 if (!IS_FIXNUM(obj)) { \
118 WRONG_ARG_ERR(); \ 110 RUNTIME_ERROR(ERR_WRONG_ARG_TYPE); \
119 return; \ 111 return; \
120 } \ 112 } \
121 ssize_t current = AS_FIXNUM(obj); \ 113 ssize_t current = AS_FIXNUM(obj); \
@@ -184,7 +176,7 @@ vm_interpret(VM *vm) {
184 Object name = array_pop(vm->stack); 176 Object name = array_pop(vm->stack);
185 Object *prev = ht_lookup(vm->globals, name); 177 Object *prev = ht_lookup(vm->globals, name);
186 if (prev == NULL) { 178 if (prev == NULL) {
187 SYMBOL_NOT_FOUND_ERR(); 179 RUNTIME_ERROR(ERR_SYMBOL_NOT_FOUND);
188 return; 180 return;
189 } 181 }
190 ht_insert(vm->globals, name, value); 182 ht_insert(vm->globals, name, value);
@@ -193,7 +185,7 @@ vm_interpret(VM *vm) {
193 Object name = array_pop(vm->stack); 185 Object name = array_pop(vm->stack);
194 Object *value = ht_lookup(vm->globals, name); 186 Object *value = ht_lookup(vm->globals, name);
195 if (value == NULL) { 187 if (value == NULL) {
196 SYMBOL_NOT_FOUND_ERR(); 188 RUNTIME_ERROR(ERR_SYMBOL_NOT_FOUND);
197 return; 189 return;
198 } 190 }
199 array_push(vm->stack, *value); 191 array_push(vm->stack, *value);
@@ -235,7 +227,7 @@ vm_interpret(VM *vm) {
235 case OP_PRINT: { 227 case OP_PRINT: {
236 Object obj = array_pop(vm->stack); 228 Object obj = array_pop(vm->stack);
237 if (!IS_STRING(obj)) { 229 if (!IS_STRING(obj)) {
238 WRONG_ARG_ERR(); 230 RUNTIME_ERROR(ERR_WRONG_ARG_TYPE);
239 } 231 }
240 StringView scanner = (StringView) { 232 StringView scanner = (StringView) {
241 .start = obj.text, 233 .start = obj.text,
@@ -260,7 +252,20 @@ vm_interpret(VM *vm) {
260 printf("\n"); 252 printf("\n");
261 } break; 253 } break;
262 case OP_CALL: { 254 case OP_CALL: {
255 ssize_t n_args = AS_FIXNUM(array_pop(vm->stack));
263 Object proc = array_pop(vm->stack); 256 Object proc = array_pop(vm->stack);
257
258 // Check the number of arguments is correct.
259 // NOTE: This is probably better handled at compilation, but for
260 // now this is simpler to implement.
261 ssize_t n_params = array_size(proc.chunk->params);
262 if (n_args < n_params) {
263 RUNTIME_ERROR(ERR_NOT_ENOUGH_ARGS);
264 } else if (n_args > n_params) {
265 RUNTIME_ERROR(ERR_TOO_MANY_ARGS);
266 }
267
268 // DEBUG:...
264 // disassemble_chunk(proc.chunk); 269 // disassemble_chunk(proc.chunk);
265 270
266 // Tail-call optimization. 271 // Tail-call optimization.
@@ -299,13 +304,7 @@ vm_interpret(VM *vm) {
299 array_head(vm->stack)->size = 0; 304 array_head(vm->stack)->size = 0;
300 } break; 305 } break;
301 default: { 306 default: {
302 error_push((Error){ 307 RUNTIME_ERROR(ERR_NOT_IMPLEMENTED);
303 .type = ERR_TYPE_RUNTIME,
304 .value = ERR_NOT_IMPLEMENTED,
305 .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line,
306 .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col,
307 });
308 return;
309 } break; 308 } break;
310 } 309 }
311 } 310 }