diff options
Diffstat (limited to 'src/bytecode')
-rwxr-xr-x | src/bytecode/compiler.h | 4 | ||||
-rwxr-xr-x | src/bytecode/vm.h | 47 |
2 files changed, 25 insertions, 26 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index 44f03fc..995a5c1 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -350,8 +350,6 @@ compile_fun_op(Chunk *chunk, Compiler *compiler, Token start) { | |||
350 | 350 | ||
351 | void | 351 | void |
352 | compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { | 352 | compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { |
353 | // FIXME: skipping arguments for now. Assuming nil. | ||
354 | |||
355 | // Compile body. | 353 | // Compile body. |
356 | size_t n = 0; | 354 | size_t n = 0; |
357 | while (has_next_token(compiler)) { | 355 | while (has_next_token(compiler)) { |
@@ -370,12 +368,14 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { | |||
370 | break; | 368 | break; |
371 | } | 369 | } |
372 | parse_tree(chunk, compiler); | 370 | parse_tree(chunk, compiler); |
371 | n++; | ||
373 | } | 372 | } |
374 | if (name.type == TOKEN_SYMBOL) { | 373 | if (name.type == TOKEN_SYMBOL) { |
375 | Object obj = make_symbol(name.value); | 374 | Object obj = make_symbol(name.value); |
376 | emit_constant(chunk, start, obj); | 375 | emit_constant(chunk, start, obj); |
377 | add_code(chunk, OP_GET, start.line, start.column); | 376 | add_code(chunk, OP_GET, start.line, start.column); |
378 | } | 377 | } |
378 | emit_constant(chunk, start, FIXNUM_VAL(n)); | ||
379 | add_code(chunk, OP_CALL, start.line, start.column); | 379 | add_code(chunk, OP_CALL, start.line, start.column); |
380 | } | 380 | } |
381 | 381 | ||
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 | } |