#ifndef BDL_DEBUG_H #define BDL_DEBUG_H #include "chunk.h" #include "objects.h" void disassemble_chunk(Chunk *chunk); size_t disassemble_instruction(Chunk *chunk, size_t offset); static const char* ops_str[] = { // Load/store ops. [OP_CONSTANT] = "OP_CONSTANT", [OP_LOCAL] = "OP_LOCAL", [OP_DEF_LOCAL] = "OP_DEF_LOCAL", [OP_SET_LOCAL] = "OP_SET_LOCAL", [OP_DEF] = "OP_DEF", [OP_SET] = "OP_SET", [OP_GET] = "OP_GET", // Arithmetic ops. [OP_SUM] = "OP_SUM", [OP_SUB] = "OP_SUB", [OP_MUL] = "OP_MUL", [OP_DIV] = "OP_DIV", [OP_MOD] = "OP_MOD", // Logic ops. [OP_NOT] = "OP_NOT", [OP_AND] = "OP_AND", [OP_OR] = "OP_OR", // Numerical comparison ops. [OP_EQUAL] = "OP_EQUAL", [OP_LESS] = "OP_LESS", [OP_GREATER] = "OP_GREATER", [OP_LESS_EQUAL] = "OP_LESS_EQUAL", [OP_GREATER_EQUAL] = "OP_GREATER_EQUAL", // Jump/conditional ops. [OP_JUMP] = "OP_JUMP", [OP_JUMP_IF_FALSE] = "OP_JUMP_IF_FALSE", // Display ops. [OP_DISPLAY] = "OP_DISPLAY", [OP_PRINT] = "OP_PRINT", [OP_NEWLINE] = "OP_NEWLINE", // Procedures. [OP_CALL] = "OP_CALL", [OP_RETURN] = "OP_RETURN", // Clear stack after each statement. [OP_DROP] = "OP_DROP", }; void disassemble_chunk(Chunk *chunk) { if (array_size(chunk->name) < 1) { printf("===== main =====\n"); } else { printf("===== %.*s =====\n", (int)array_size(chunk->name), chunk->name); } printf("code:\n"); size_t offset = 0; while (offset < array_size(chunk->code)) { offset = disassemble_instruction(chunk, offset); } printf("\nconstants:\n"); offset = 0; while (offset < array_size(chunk->constants)) { printf("\t%03ld -> ", offset); object_display(chunk->constants[offset]); printf("\n"); offset++; } printf("\n"); } size_t disassemble_instruction(Chunk *chunk, size_t offset) { printf("\t%04ld ", offset); if (offset > 0 && chunk->lines[offset].line == chunk->lines[offset - 1].line && chunk->lines[offset].col == chunk->lines[offset - 1].col) { printf("%4s|%-4s ", " ", " "); } else { printf("%4ld:%-4ld ", chunk->lines[offset].line, chunk->lines[offset].col); } u8 instruction = chunk->code[offset]; switch (instruction) { case OP_LOCAL: { u8 local = chunk->code[offset + 1]; printf("%-16s %4d\n", ops_str[instruction], local); return offset + 2; } break; case OP_CONSTANT: { u8 constant = chunk->code[offset + 1]; printf("%-16s %4d -> ", ops_str[instruction], constant); object_display(chunk->constants[constant]); printf("\n"); return offset + 2; } break; case OP_JUMP: case OP_JUMP_IF_FALSE: { u16 a = chunk->code[offset + 1]; u16 b = chunk->code[offset + 2]; s16 jmp = (a << 8) | b; printf("%-16s %4d\n", ops_str[instruction], jmp); return offset + 3; } break; default: { printf("%s\n", ops_str[instruction]); return offset + 1; } break; } } #endif // BDL_DEBUG_H