aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-24 15:42:01 +0200
committerBad Diode <bd@badd10de.dev>2021-10-24 15:42:01 +0200
commitdd5210368634e2b322435385eaaaccaa5125b5a9 (patch)
tree81c2bb47907281a82a198ed8cb28d9b7e34e7bf3 /src/bytecode
parentd90b9f42a361bc3563b1f11bbd707c4288a65b40 (diff)
downloadbdl-dd5210368634e2b322435385eaaaccaa5125b5a9.tar.gz
bdl-dd5210368634e2b322435385eaaaccaa5125b5a9.zip
Add initial IF implementation
Diffstat (limited to 'src/bytecode')
-rwxr-xr-xsrc/bytecode/compiler.h66
-rwxr-xr-xsrc/bytecode/debug.h3
-rwxr-xr-xsrc/bytecode/ops.h3
-rwxr-xr-xsrc/bytecode/vm.h10
4 files changed, 82 insertions, 0 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index b1cdfb9..559ad1c 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -232,6 +232,71 @@ compile_declare_op(Chunk *chunk, Visitor *vs, Token start, Ops op) {
232} 232}
233 233
234void 234void
235compile_if_op(Chunk *chunk, Visitor *vs, Token start) {
236 Token tok = peek_token(vs);
237 if (tok.type == TOKEN_EOF) {
238 error_push((Error){
239 .type = ERR_TYPE_COMPILER,
240 .value = ERR_UNBALANCED_PAREN,
241 .line = start.line,
242 .col = start.column,
243 });
244 return;
245 }
246 if (tok.type == TOKEN_RPAREN) {
247 error_push((Error){
248 .type = ERR_TYPE_COMPILER,
249 .value = ERR_NOT_ENOUGH_ARGS,
250 .line = start.line,
251 .col = start.column,
252 });
253 return;
254 }
255
256 // Condition.
257 parse_tree(chunk, vs);
258 emit_constant(chunk, tok, FIXNUM_VAL(0xFF));
259 size_t pos = array_size(chunk->code);
260 add_code(chunk, OP_JUMP_IF_FALSE, start.line, start.column);
261
262 // Block true.
263 parse_tree(chunk, vs);
264
265 // No else.
266 if (peek_token(vs).type == TOKEN_RPAREN) {
267 size_t false_block_start = array_size(chunk->code) - pos - 1;
268 size_t num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start));
269 chunk->code[pos - 1] = num_idx;
270 next_token(vs);
271 return;
272 }
273
274 // Else.
275 emit_constant(chunk, tok, FIXNUM_VAL(0xFF));
276 size_t else_pos = array_size(chunk->code);
277 add_code(chunk, OP_JUMP, start.line, start.column);
278
279 size_t false_block_start = array_size(chunk->code) - pos - 1;
280 size_t num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start));
281 chunk->code[pos - 1] = num_idx;
282 parse_tree(chunk, vs);
283 false_block_start = array_size(chunk->code) - else_pos - 1;
284 num_idx = add_constant(chunk, FIXNUM_VAL(false_block_start));
285 chunk->code[else_pos - 1] = num_idx;
286
287 if (peek_token(vs).type != TOKEN_RPAREN) {
288 error_push((Error){
289 .type = ERR_TYPE_COMPILER,
290 .value = ERR_TOO_MANY_ARGS,
291 .line = start.line,
292 .col = start.column,
293 });
294 return;
295 }
296 next_token(vs);
297}
298
299void
235parse_list(Chunk *chunk, Visitor *vs, Token start) { 300parse_list(Chunk *chunk, Visitor *vs, Token start) {
236 if (!has_next_token(vs)) { 301 if (!has_next_token(vs)) {
237 error_push((Error){ 302 error_push((Error){
@@ -262,6 +327,7 @@ parse_list(Chunk *chunk, Visitor *vs, Token start) {
262 case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break; 327 case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break;
263 case TOKEN_DEF: { compile_declare_op(chunk, vs, start, OP_DEF); } break; 328 case TOKEN_DEF: { compile_declare_op(chunk, vs, start, OP_DEF); } break;
264 case TOKEN_SET: { compile_declare_op(chunk, vs, start, OP_SET); } break; 329 case TOKEN_SET: { compile_declare_op(chunk, vs, start, OP_SET); } break;
330 case TOKEN_IF: { compile_if_op(chunk, vs, start); } break;
265 default: { 331 default: {
266 error_push((Error){ 332 error_push((Error){
267 .type = ERR_TYPE_COMPILER, 333 .type = ERR_TYPE_COMPILER,
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h
index 889ae03..674d469 100755
--- a/src/bytecode/debug.h
+++ b/src/bytecode/debug.h
@@ -28,6 +28,9 @@ static const char* ops_str[] = {
28 [OP_GREATER] = "OP_GREATER", 28 [OP_GREATER] = "OP_GREATER",
29 [OP_LESS_EQUAL] = "OP_LESS_EQUAL", 29 [OP_LESS_EQUAL] = "OP_LESS_EQUAL",
30 [OP_GREATER_EQUAL] = "OP_GREATER_EQUAL", 30 [OP_GREATER_EQUAL] = "OP_GREATER_EQUAL",
31 // Jump/conditional ops.
32 [OP_JUMP] = "OP_JUMP",
33 [OP_JUMP_IF_FALSE] = "OP_JUMP_IF_FALSE",
31 // Display ops. 34 // Display ops.
32 [OP_DISPLAY] = "OP_DISPLAY", 35 [OP_DISPLAY] = "OP_DISPLAY",
33 [OP_PRINT] = "OP_PRINT", 36 [OP_PRINT] = "OP_PRINT",
diff --git a/src/bytecode/ops.h b/src/bytecode/ops.h
index 50d12fe..5eacaea 100755
--- a/src/bytecode/ops.h
+++ b/src/bytecode/ops.h
@@ -23,6 +23,9 @@ typedef enum Ops {
23 OP_GREATER, 23 OP_GREATER,
24 OP_LESS_EQUAL, 24 OP_LESS_EQUAL,
25 OP_GREATER_EQUAL, 25 OP_GREATER_EQUAL,
26 // Jump/conditional ops.
27 OP_JUMP,
28 OP_JUMP_IF_FALSE,
26 // Display ops. 29 // Display ops.
27 OP_DISPLAY, 30 OP_DISPLAY,
28 OP_PRINT, 31 OP_PRINT,
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 51a6f44..b24a5fa 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -196,6 +196,16 @@ vm_interpret(VM *vm, Chunk *chunk) {
196 case OP_GREATER: { FIXNUM_COMPARE_OP(>); } break; 196 case OP_GREATER: { FIXNUM_COMPARE_OP(>); } break;
197 case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; 197 case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break;
198 case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; 198 case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break;
199 case OP_JUMP: {
200 ssize_t off = AS_FIXNUM(array_pop(vm->stack));
201 vm->pc += off;
202 } break;
203 case OP_JUMP_IF_FALSE: {
204 ssize_t off = AS_FIXNUM(array_pop(vm->stack));
205 if (IS_FALSE(array_pop(vm->stack))) {
206 vm->pc += off;
207 }
208 } break;
199 case OP_DISPLAY: { 209 case OP_DISPLAY: {
200 display(array_pop(vm->stack)); 210 display(array_pop(vm->stack));
201 } break; 211 } break;