aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
parentb07ece568d8d62ca80a8ba3b43fb46a98e117d5a (diff)
downloadbdl-b271ce1d9098c9057fccdca6eba6b0ee0a5245a2.tar.gz
bdl-b271ce1d9098c9057fccdca6eba6b0ee0a5245a2.zip
Change relevant OPs to use list operations
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bytecode/compiler.h14
-rwxr-xr-xsrc/bytecode/objects.h1
-rwxr-xr-xsrc/bytecode/vm.h99
3 files changed, 65 insertions, 49 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index 6f43416..7a25678 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -80,21 +80,15 @@ compile_list_binary_op(Chunk *chunk, Visitor *vs, Token list_start, Ops op) {
80 .line = list_start.line, 80 .line = list_start.line,
81 .col = list_start.column, 81 .col = list_start.column,
82 }); 82 });
83 return;
83 } 84 }
84 return; 85 break;
85 } 86 }
86 parse_tree(chunk, vs); 87 parse_tree(chunk, vs);
87 n++; 88 n++;
88 if (n > 1) {
89 add_code(chunk, op, list_start.line, list_start.column);
90 }
91 } 89 }
92 error_push((Error){ 90 emit_constant(chunk, list_start, FIXNUM_VAL(n));
93 .type = ERR_TYPE_COMPILER, 91 add_code(chunk, op, list_start.line, list_start.column);
94 .value = ERR_NOT_ENOUGH_ARGS,
95 .line = list_start.line,
96 .col = list_start.column,
97 });
98} 92}
99 93
100void 94void
diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h
index a25b0b1..35a954f 100755
--- a/src/bytecode/objects.h
+++ b/src/bytecode/objects.h
@@ -50,6 +50,7 @@ void display(Object obj);
50#define TRUE_VAL ((Object){.type = OBJ_TYPE_TRUE}) 50#define TRUE_VAL ((Object){.type = OBJ_TYPE_TRUE})
51#define FALSE_VAL ((Object){.type = OBJ_TYPE_FALSE}) 51#define FALSE_VAL ((Object){.type = OBJ_TYPE_FALSE})
52#define FIXNUM_VAL(VAL) ((Object){.type = OBJ_TYPE_FIXNUM, .fixnum = VAL}) 52#define FIXNUM_VAL(VAL) ((Object){.type = OBJ_TYPE_FIXNUM, .fixnum = VAL})
53#define BOOL_VAL(VAL) ((VAL) ? TRUE_VAL : FALSE_VAL)
53 54
54// Value extraction. 55// Value extraction.
55#define AS_FIXNUM(VAL) ((VAL).fixnum) 56#define AS_FIXNUM(VAL) ((VAL).fixnum)
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