diff options
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-x | src/bytecode/vm.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 9b68fc1..c94e22b 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -59,6 +59,35 @@ vm_reset(VM *vm) { | |||
59 | array_push(vm->stack, FIXNUM_VAL(y OP x)); \ | 59 | array_push(vm->stack, FIXNUM_VAL(y OP x)); \ |
60 | } while (false) | 60 | } while (false) |
61 | 61 | ||
62 | #define FIXNUM_CMP_OP(OP) \ | ||
63 | do { \ | ||
64 | Object a = array_pop(vm->stack); \ | ||
65 | Object b = array_pop(vm->stack); \ | ||
66 | if (!IS_FIXNUM(a) || !IS_FIXNUM(b)) { \ | ||
67 | error_push((Error){ \ | ||
68 | .type = ERR_TYPE_RUNTIME, \ | ||
69 | .value = ERR_WRONG_ARG_TYPE, \ | ||
70 | .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \ | ||
71 | .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \ | ||
72 | }); \ | ||
73 | return; \ | ||
74 | } \ | ||
75 | ssize_t x = AS_FIXNUM(a); \ | ||
76 | ssize_t y = AS_FIXNUM(b); \ | ||
77 | Object result = y OP x ? TRUE_VAL : FALSE_VAL; \ | ||
78 | array_push(vm->stack, result); \ | ||
79 | } while (false) | ||
80 | |||
81 | #define LOGIC_OP(OP) \ | ||
82 | do { \ | ||
83 | Object a = array_pop(vm->stack); \ | ||
84 | Object b = array_pop(vm->stack); \ | ||
85 | bool x = IS_TRUE(a); \ | ||
86 | bool y = IS_TRUE(b); \ | ||
87 | Object result = y OP x ? TRUE_VAL : FALSE_VAL; \ | ||
88 | array_push(vm->stack, result); \ | ||
89 | } while (false) | ||
90 | |||
62 | void | 91 | void |
63 | vm_interpret(VM *vm, Chunk *chunk) { | 92 | vm_interpret(VM *vm, Chunk *chunk) { |
64 | vm->chunk = chunk; | 93 | vm->chunk = chunk; |
@@ -97,6 +126,18 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
97 | case OP_MUL: { FIXNUM_BINARY_OP(*); } break; | 126 | case OP_MUL: { FIXNUM_BINARY_OP(*); } break; |
98 | case OP_DIV: { FIXNUM_BINARY_OP(/); } break; | 127 | case OP_DIV: { FIXNUM_BINARY_OP(/); } break; |
99 | case OP_MOD: { FIXNUM_BINARY_OP(%); } break; | 128 | case OP_MOD: { FIXNUM_BINARY_OP(%); } break; |
129 | case OP_NOT: { | ||
130 | Object prev = array_pop(vm->stack); | ||
131 | Object new = IS_TRUE(prev) ? FALSE_VAL : TRUE_VAL; | ||
132 | array_push(vm->stack, new); | ||
133 | } break; | ||
134 | case OP_AND: { LOGIC_OP(&&); } break; | ||
135 | case OP_OR: { LOGIC_OP(||); } break; | ||
136 | case OP_EQUAL: { FIXNUM_CMP_OP(==); } break; | ||
137 | case OP_LESS: { FIXNUM_CMP_OP(<); } break; | ||
138 | case OP_GREATER: { FIXNUM_CMP_OP(>); } break; | ||
139 | case OP_LESS_EQUAL: { FIXNUM_CMP_OP(<=); } break; | ||
140 | case OP_GREATER_EQUAL: { FIXNUM_CMP_OP(>=); } break; | ||
100 | case OP_RETURN: { | 141 | case OP_RETURN: { |
101 | display(array_pop(vm->stack)); | 142 | display(array_pop(vm->stack)); |
102 | printf("\n"); | 143 | printf("\n"); |
@@ -123,5 +164,7 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
123 | } | 164 | } |
124 | 165 | ||
125 | #undef FIXNUM_BINARY_OP | 166 | #undef FIXNUM_BINARY_OP |
167 | #undef FIXNUM_CMP_OP | ||
168 | #undef LOGIC_OP | ||
126 | 169 | ||
127 | #endif // BDL_VM_H | 170 | #endif // BDL_VM_H |