use chunk; use fmt; use value; export fn disassemble_chunk(chunk: *chunk::chunk, name: str) void = { fmt::printf("== {} ==\n", name)!; for (let idx = 0z; idx < len(chunk.code)) { idx = dissassemble_instruction(chunk, idx); }; }; export fn dissassemble_instruction(chunk: *chunk::chunk, idx: size) size = { fmt::printf("{:4_0} ", idx)!; const line = chunk::get_line(chunk, idx); if (idx > 0 && line == chunk::get_line(chunk, idx - 1)) { fmt::print(" | ")!; } else { fmt::printf("{:4} ", line)!; }; let instruction = chunk.code[idx]; switch (instruction) { case chunk::opcode::RETURN => return simple_instruction("RETURN", idx); case chunk::opcode::CONSTANT => return constant_instruction("CONSTANT", chunk, idx); case chunk::opcode::CONSTANT_LONG => return long_constant_instruction("CONSTANT_LONG", chunk, idx); case => fmt::printf("Unknown opcode: {}\n", instruction)!; return idx + 1; }; }; fn simple_instruction(name: str, idx: size) size = { fmt::printf("{}\n", name)!; return idx + 1; }; fn constant_instruction(name: str, chunk: *chunk::chunk, idx: size) size = { const constant = chunk.code[idx + 1]; fmt::printf("{:-16} {:4} '", name, constant)!; value::print_value(chunk.constants[constant]); fmt::print("'\n")!; return idx + 2; }; fn long_constant_instruction(name: str, chunk: *chunk::chunk, idx: size) size = { const constant1: size = chunk.code[idx + 1]; const constant2: size = chunk.code[idx + 2]; const constant3: size = chunk.code[idx + 3]; const constant = (constant3 << 16) + (constant2 << 8) + constant1; fmt::printf("{:-16} {} '", name, constant)!; value::print_value(chunk.constants[constant]); fmt::print("'\n")!; return idx + 4; };