#include "dis.h" #include #include #include static void print_const(Chunk *ch, uint8_t ix) { Val k = ch->consts.d[ix]; printf("%-4s : ", typename_str(k)); println_val(k); } void disasm_chunk(Chunk *ch) { puts("constants:"); for (uint8_t cix = 0; cix < ch->consts.len; cix++) { printf("%hd\t",cix); print_const(ch, cix); } puts("bytecode:"); for (size_t ip = 0; ip < ch->bc.len; ) { uint8_t instr = ch->bc.d[ip]; printf("%04zd\t",ip); ip ++; switch (instr) { case OP_LOADK: { uint8_t ix = ch->bc.d[ip++]; printf("loadk #%d\t; ",ix); print_const(ch, ix); break; } case OP_GETGLOBAL: { uint8_t ix = ch->bc.d[ip++]; printf("getglobal #%d\t; ",ix); print_const(ch, ix); break; } case OP_SETGLOBAL: { uint8_t ix = ch->bc.d[ip++]; printf("setglobal #%d\t; ",ix); print_const(ch, ix); break; } #define RSHORT() (uint16_t)( ch->bc.d[ip-2] | ch->bc.d[ip-1] << 8 ) case OP_SKIP: { ip += 2; uint16_t offset = RSHORT(); printf("skip +%5hu\t; -> %04zd\n", offset, ip + offset); break; } case OP_0BRANCH: { ip += 2; uint16_t offset = RSHORT(); printf("0branch +%5hu\t; -> %04zd\n", offset, ip + offset); break; } case OP_REDO: { ip += 2; uint16_t offset = RSHORT(); printf("redo -%5hu\t; -> %04zd\n", offset, ip - offset); break; } #undef RSHORT #define SIMPLE_INSTR(opcode, str) \ case opcode: puts(str); break; SIMPLE_INSTR(OP_RET, "ret") SIMPLE_INSTR(OP_PRINT, "print") SIMPLE_INSTR(OP_DROP, "drop") SIMPLE_INSTR(OP_ADD, "add") SIMPLE_INSTR(OP_SUB, "sub") SIMPLE_INSTR(OP_MUL, "mul") SIMPLE_INSTR(OP_DIV, "div") SIMPLE_INSTR(OP_MOD, "mod") SIMPLE_INSTR(OP_NIL, "nil") SIMPLE_INSTR(OP_TRUE, "true") SIMPLE_INSTR(OP_FALSE, "false") SIMPLE_INSTR(OP_CMP, "cmp") SIMPLE_INSTR(OP_EQU, "equ") #undef SIMPLE_INSTR default: printf("unknown opcode %d\n", instr); exit(2); } } }