diff options
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-x | src/bytecode/vm.h | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 581f093..9b68fc1 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -40,6 +40,25 @@ vm_reset(VM *vm) { | |||
40 | vm_init(vm); | 40 | vm_init(vm); |
41 | } | 41 | } |
42 | 42 | ||
43 | // Helper macros for a more clear VM switch. | ||
44 | #define FIXNUM_BINARY_OP(OP) \ | ||
45 | do { \ | ||
46 | Object a = array_pop(vm->stack); \ | ||
47 | Object b = array_pop(vm->stack); \ | ||
48 | if (!IS_FIXNUM(a) || !IS_FIXNUM(b)) { \ | ||
49 | error_push((Error){ \ | ||
50 | .type = ERR_TYPE_RUNTIME, \ | ||
51 | .value = ERR_WRONG_ARG_TYPE, \ | ||
52 | .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ | ||
53 | .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ | ||
54 | }); \ | ||
55 | return; \ | ||
56 | } \ | ||
57 | ssize_t x = AS_FIXNUM(a); \ | ||
58 | ssize_t y = AS_FIXNUM(b); \ | ||
59 | array_push(vm->stack, FIXNUM_VAL(y OP x)); \ | ||
60 | } while (false) | ||
61 | |||
43 | void | 62 | void |
44 | vm_interpret(VM *vm, Chunk *chunk) { | 63 | vm_interpret(VM *vm, Chunk *chunk) { |
45 | vm->chunk = chunk; | 64 | vm->chunk = chunk; |
@@ -73,31 +92,11 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
73 | Object obj = vm->chunk->constants[constant]; | 92 | Object obj = vm->chunk->constants[constant]; |
74 | array_push(vm->stack, obj); | 93 | array_push(vm->stack, obj); |
75 | } break; | 94 | } break; |
76 | case OP_SUM: { | 95 | case OP_SUM: { FIXNUM_BINARY_OP(+); } break; |
77 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); | 96 | case OP_SUB: { FIXNUM_BINARY_OP(-); } break; |
78 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); | 97 | case OP_MUL: { FIXNUM_BINARY_OP(*); } break; |
79 | array_push(vm->stack, FIXNUM_VAL(a + b)); | 98 | case OP_DIV: { FIXNUM_BINARY_OP(/); } break; |
80 | } break; | 99 | case OP_MOD: { FIXNUM_BINARY_OP(%); } break; |
81 | case OP_SUB: { | ||
82 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); | ||
83 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); | ||
84 | array_push(vm->stack, FIXNUM_VAL(b - a)); | ||
85 | } break; | ||
86 | case OP_MUL: { | ||
87 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); | ||
88 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); | ||
89 | array_push(vm->stack, FIXNUM_VAL(a * b)); | ||
90 | } break; | ||
91 | case OP_DIV: { | ||
92 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); | ||
93 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); | ||
94 | array_push(vm->stack, FIXNUM_VAL(b / a)); | ||
95 | } break; | ||
96 | case OP_MOD: { | ||
97 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); | ||
98 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); | ||
99 | array_push(vm->stack, FIXNUM_VAL(a % b)); | ||
100 | } break; | ||
101 | case OP_RETURN: { | 100 | case OP_RETURN: { |
102 | display(array_pop(vm->stack)); | 101 | display(array_pop(vm->stack)); |
103 | printf("\n"); | 102 | printf("\n"); |
@@ -107,8 +106,8 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
107 | error_push((Error){ | 106 | error_push((Error){ |
108 | .type = ERR_TYPE_RUNTIME, | 107 | .type = ERR_TYPE_RUNTIME, |
109 | .value = ERR_NOT_IMPLEMENTED, | 108 | .value = ERR_NOT_IMPLEMENTED, |
110 | .line = vm->chunk->lines[(vm->pc - vm->chunk->code) - 1].line, | 109 | .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, |
111 | .col = vm->chunk->lines[(vm->pc - vm->chunk->code) - 1].col, | 110 | .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, |
112 | }); | 111 | }); |
113 | return; | 112 | return; |
114 | } break; | 113 | } break; |
@@ -123,4 +122,6 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
123 | }); | 122 | }); |
124 | } | 123 | } |
125 | 124 | ||
125 | #undef FIXNUM_BINARY_OP | ||
126 | |||
126 | #endif // BDL_VM_H | 127 | #endif // BDL_VM_H |