#include "us_debug.h" #include #include "dyn_arr.h" #include "vm.h" static char *bc_names[] = { #define BC(name) "BC_" #name, #include "xbytecode.h" #undef BC }; int print_instruction(struct us_proto *proto, int idx) { enum bytecode instruction = proto->bytecode[idx]; fprintf(stderr, "%04d %-15s ", idx, bc_names[instruction]); switch (instruction) { case BC_LOAD: { int const_idx = proto->bytecode[idx + 1]; char *const_str = val_to_str(proto->constants[const_idx], NULL); fprintf( stderr, "%d (%s)\n", const_idx, const_str ); mem_free(const_str); return idx + 2; } case BC_LOAD_FUNC: { int const_idx = proto->bytecode[idx + 1]; assert(proto->constants[const_idx].type == VAL_PROTO); struct us_proto *p = get_proto(proto->constants[const_idx]); int upvalc = p->upvalc; fprintf( stderr, "%.*s() %d\n", (int)p->name->len, p->name->chars, upvalc ); return idx + 2 + upvalc * 2; } case BC_SMALL_INT: case BC_ARR: case BC_GET_UPVAL: case BC_SET_UPVAL: case BC_GET_LOCAL: case BC_SET_LOCAL: case BC_CALL: { fprintf( stderr, "%d\n", proto->bytecode[idx + 1] ); return idx + 2; } case BC_GET_GLOBAL: case BC_SET_GLOBAL: { u16 loc = (u16)(proto->bytecode[idx + 1] << 8) | proto->bytecode[idx + 2]; fprintf(stderr, "%d\n", loc); return idx + 3; } case BC_JMP: case BC_FALSEY_JMP: case BC_LOOP: { u16 jmp = (u16)(proto->bytecode[idx + 1] << 8) | proto->bytecode[idx + 2]; int dst = idx + jmp + 3; if (instruction == BC_LOOP) { dst = idx + 3 - jmp; } fprintf( stderr, "-> %04d\n", dst ); return idx + 3; } case BC_FALSE: case BC_TRUE: case BC_ZILCH: case BC_GET_INDEX: case BC_SET_INDEX: case BC_POP: case BC_POP_UPVAL: case BC_ADD: case BC_SUB: case BC_MULT: case BC_DIV: case BC_MOD: case BC_GT: case BC_GTE: case BC_LT: case BC_LTE: case BC_NEG: case BC_NOT: case BC_EQL: case BC_NEQL: case BC_CONCAT: case BC_PRINT: case BC_RET: putc('\n', stderr); return idx + 1; } // unreachable return idx + 1; } void print_func(struct us_proto *func) { fprintf(stderr, "%s():\n", func->name->chars); for (int i = 0; i < da_len(func->bytecode);) { putc('\t', stderr); i = print_instruction(func, i); } }