diff --git a/lang/bytecode.c b/lang/bytecode.c index 7531b10..cb4ebe7 100644 --- a/lang/bytecode.c +++ b/lang/bytecode.c @@ -7,15 +7,19 @@ #include "object.h" #include "vm.h" +// Opcode definitions, see bytecode_run for further documentation enum opcodes { + // 0x00 is reserved for inline strings OP_NUM = 0x01, OP_RET = 0x03, + // 0x02 was an earlier variant of OP_DROP OP_CALL = 0x04, OP_NULL = 0x05, OP_GET = 0x06, OP_SET = 0x07, OP_DROP = 0x08, OP_DEPTH_CHECK = 0x09, + // 0x60 onwards are reserved for inline strings }; // clang-format off @@ -34,6 +38,8 @@ unsigned char op = OP_RET; while ((op = *pos_code++) != OP_RET) { switch (op) { + // OP_NUM pushes a number on to the stack + // First argument is a 4-byte little endian number case OP_NUM: { int num = 0; num |= *pos_code++ << 0; @@ -43,6 +49,9 @@ vm_stack_push(state, number_create(num)); break; } + // OP_CALL dispatches a call to the top of stack object + // First argument is a 1-byte argument count + // Second argument is the call string case OP_CALL: { int arg_count = *pos_code++; const char *dispatch = (const char *)pos_code; @@ -51,32 +60,43 @@ object_drop(&obj); break; } + // OP_NULL pushes object_none on to the stack case OP_NULL: { vm_stack_push(state, object_none()); break; } + // OP_GET duplicates an element from the stack and stores + // the result at the top + // First argument is the stack index case OP_GET: { Object obj = vm_stack_get(state, *pos_code++); vm_stack_push(state, obj); break; } + // OP_SET stores the stack top element at a stack index + // The stack top element is dropped in the process + // First argument is the stack index case OP_SET: { Object obj = vm_stack_pop(state); vm_stack_set(state, *pos_code++, obj); break; } + // OP_DROP drops multiple stack elements starting at the top + // First argument is the number of elements to drop case OP_DROP: { vm_stack_drop(state, *pos_code++); break; } + // OP_DEPTH_CHECK checks that the stack is a certain size + // First argument is the expected depth case OP_DEPTH_CHECK: { int depth = *pos_code++; abort_if(vm_stack_depth(state) != depth, "stack depth mismatch"); break; } + // Skip over strings and unknown OPs default: - // Skip over ASCII and unknown OPs break; } }