aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode/vm.h
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-23 19:47:50 +0200
committerBad Diode <bd@badd10de.dev>2021-10-23 19:47:50 +0200
commitb271ce1d9098c9057fccdca6eba6b0ee0a5245a2 (patch)
treee7b5a5f55e317f7ef6cd090eb12edc421f68504a /src/bytecode/vm.h
parentb07ece568d8d62ca80a8ba3b43fb46a98e117d5a (diff)
downloadbdl-b271ce1d9098c9057fccdca6eba6b0ee0a5245a2.tar.gz
bdl-b271ce1d9098c9057fccdca6eba6b0ee0a5245a2.zip
Change relevant OPs to use list operations
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-xsrc/bytecode/vm.h99
1 files changed, 60 insertions, 39 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index c94e22b..b3dd8c3 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -41,41 +41,62 @@ vm_reset(VM *vm) {
41} 41}
42 42
43// Helper macros for a more clear VM switch. 43// Helper macros for a more clear VM switch.
44#define FIXNUM_BINARY_OP(OP) \ 44#define WRONG_ARG_ERR() \
45 error_push((Error){ \
46 .type = ERR_TYPE_RUNTIME, \
47 .value = ERR_WRONG_ARG_TYPE, \
48 .line = vm->chunk->lines[vm->pc - vm->chunk->code - 1].line, \
49 .col = vm->chunk->lines[vm->pc - vm->chunk->code - 1].col, \
50 })
51
52#define FIXNUM_ARITHMETIC_OP(OP) \
45 do { \ 53 do { \
46 Object a = array_pop(vm->stack); \ 54 ssize_t n = AS_FIXNUM(array_pop(vm->stack)); \
47 Object b = array_pop(vm->stack); \ 55 size_t stack_size = array_size(vm->stack) - n; \
48 if (!IS_FIXNUM(a) || !IS_FIXNUM(b)) { \ 56 Object obj = array_peek(vm->stack, n - 1); \
49 error_push((Error){ \ 57 if (!IS_FIXNUM(obj)) { \
50 .type = ERR_TYPE_RUNTIME, \ 58 WRONG_ARG_ERR(); \
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; \ 59 return; \
56 } \ 60 } \
57 ssize_t x = AS_FIXNUM(a); \ 61 ssize_t acc = AS_FIXNUM(obj); \
58 ssize_t y = AS_FIXNUM(b); \ 62 while (n > 1) { \
59 array_push(vm->stack, FIXNUM_VAL(y OP x)); \ 63 obj = array_peek(vm->stack, n - 2); \
64 if (!IS_FIXNUM(obj)) { \
65 WRONG_ARG_ERR(); \
66 return; \
67 } \
68 ssize_t current = AS_FIXNUM(obj); \
69 acc = acc OP current; \
70 n--; \
71 } \
72 array_head(vm->stack)->size = stack_size; \
73 array_push(vm->stack, FIXNUM_VAL(acc)); \
60 } while (false) 74 } while (false)
61 75
62#define FIXNUM_CMP_OP(OP) \ 76#define FIXNUM_COMPARE_OP(OP) \
63 do { \ 77 do { \
64 Object a = array_pop(vm->stack); \ 78 ssize_t n = AS_FIXNUM(array_pop(vm->stack)); \
65 Object b = array_pop(vm->stack); \ 79 size_t stack_size = array_size(vm->stack) - n; \
66 if (!IS_FIXNUM(a) || !IS_FIXNUM(b)) { \ 80 Object obj = array_peek(vm->stack, n - 1); \
67 error_push((Error){ \ 81 if (!IS_FIXNUM(obj)) { \
68 .type = ERR_TYPE_RUNTIME, \ 82 WRONG_ARG_ERR(); \
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; \ 83 return; \
74 } \ 84 } \
75 ssize_t x = AS_FIXNUM(a); \ 85 ssize_t prev = AS_FIXNUM(obj); \
76 ssize_t y = AS_FIXNUM(b); \ 86 bool ret = true; \
77 Object result = y OP x ? TRUE_VAL : FALSE_VAL; \ 87 while (n > 1) { \
78 array_push(vm->stack, result); \ 88 obj = array_peek(vm->stack, n - 2); \
89 if (!IS_FIXNUM(obj)) { \
90 WRONG_ARG_ERR(); \
91 return; \
92 } \
93 ssize_t current = AS_FIXNUM(obj); \
94 ret = ret && (prev OP current); \
95 prev = current; \
96 n--; \
97 } \
98 array_head(vm->stack)->size = stack_size; \
99 array_push(vm->stack, BOOL_VAL(ret)); \
79 } while (false) 100 } while (false)
80 101
81#define LOGIC_OP(OP) \ 102#define LOGIC_OP(OP) \
@@ -121,11 +142,11 @@ vm_interpret(VM *vm, Chunk *chunk) {
121 Object obj = vm->chunk->constants[constant]; 142 Object obj = vm->chunk->constants[constant];
122 array_push(vm->stack, obj); 143 array_push(vm->stack, obj);
123 } break; 144 } break;
124 case OP_SUM: { FIXNUM_BINARY_OP(+); } break; 145 case OP_SUM: { FIXNUM_ARITHMETIC_OP(+); } break;
125 case OP_SUB: { FIXNUM_BINARY_OP(-); } break; 146 case OP_SUB: { FIXNUM_ARITHMETIC_OP(-); } break;
126 case OP_MUL: { FIXNUM_BINARY_OP(*); } break; 147 case OP_MUL: { FIXNUM_ARITHMETIC_OP(*); } break;
127 case OP_DIV: { FIXNUM_BINARY_OP(/); } break; 148 case OP_DIV: { FIXNUM_ARITHMETIC_OP(/); } break;
128 case OP_MOD: { FIXNUM_BINARY_OP(%); } break; 149 case OP_MOD: { FIXNUM_ARITHMETIC_OP(%); } break;
129 case OP_NOT: { 150 case OP_NOT: {
130 Object prev = array_pop(vm->stack); 151 Object prev = array_pop(vm->stack);
131 Object new = IS_TRUE(prev) ? FALSE_VAL : TRUE_VAL; 152 Object new = IS_TRUE(prev) ? FALSE_VAL : TRUE_VAL;
@@ -133,11 +154,11 @@ vm_interpret(VM *vm, Chunk *chunk) {
133 } break; 154 } break;
134 case OP_AND: { LOGIC_OP(&&); } break; 155 case OP_AND: { LOGIC_OP(&&); } break;
135 case OP_OR: { LOGIC_OP(||); } break; 156 case OP_OR: { LOGIC_OP(||); } break;
136 case OP_EQUAL: { FIXNUM_CMP_OP(==); } break; 157 case OP_EQUAL: { FIXNUM_COMPARE_OP(==); } break;
137 case OP_LESS: { FIXNUM_CMP_OP(<); } break; 158 case OP_LESS: { FIXNUM_COMPARE_OP(<); } break;
138 case OP_GREATER: { FIXNUM_CMP_OP(>); } break; 159 case OP_GREATER: { FIXNUM_COMPARE_OP(>); } break;
139 case OP_LESS_EQUAL: { FIXNUM_CMP_OP(<=); } break; 160 case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break;
140 case OP_GREATER_EQUAL: { FIXNUM_CMP_OP(>=); } break; 161 case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break;
141 case OP_RETURN: { 162 case OP_RETURN: {
142 display(array_pop(vm->stack)); 163 display(array_pop(vm->stack));
143 printf("\n"); 164 printf("\n");
@@ -163,8 +184,8 @@ vm_interpret(VM *vm, Chunk *chunk) {
163 }); 184 });
164} 185}
165 186
166#undef FIXNUM_BINARY_OP 187#undef FIXNUM_ARITHMETIC_OP
167#undef FIXNUM_CMP_OP 188#undef FIXNUM_COMPARE_OP
168#undef LOGIC_OP 189#undef LOGIC_OP
169 190
170#endif // BDL_VM_H 191#endif // BDL_VM_H