//#include #include "debug.h" #include "value.h" void disassembleChunk( Chunk* chunk, const char* name ) { printChunkInfo( chunk, name ); for ( int i = 0; i < chunk->count; ) { i = disassembleInstruction( chunk, i ); } } void printChunkInfo( Chunk* chunk, const char* name ) { int codesz = chunk->count * sizeof(chunk->code[0]); int codecapsz = chunk->capacity * sizeof(chunk->code[0]); int concnt = chunk->constants.count; int concap = chunk->constants.capacity; int consz = concnt * sizeof(chunk->constants.values[0]); int concapsz = concap * sizeof(chunk->constants.values[0]); int linesz = sizeof(chunk->lines[0]) * chunk->count; int linecapsz = sizeof(chunk->lines[0]) * chunk->capacity; if ( !chunk->bDebug ) { linesz = 0; linecapsz = 0; } printf( "=== Chunk \"%s\" Info ===\n=== Code size: %d(%d) bytes ===\n" "=== Constants: %d(%d) (%d(%d) bytes) ===\n=== Debug lines size: %d(%d) bytes ===\n", name, codesz, codecapsz, concnt, concap, consz, concapsz, linesz,linecapsz ); printf( "=== Total size: %d(%d) bytes ===\n", sizeof(Chunk)+codesz+consz+linesz, sizeof(Chunk)+codecapsz+concapsz+linecapsz ); } static int constantInstruction( const char* name, Chunk* chunk, int offset ) { uint16_t cons = 0; cons = chunk->code[offset + 1]; if ( chunk->code[offset] == OP_CONSTANT_LONG ) { name = "OP_CONSTANT_LONG"; cons = readChunk16( chunk, offset + 1 ); } printf( "%-16s %05u '", name, cons ); Value conVal = -9001; // cons index out of range if ( cons < chunk->constants.count ) conVal = chunk->constants.values[cons]; printValue( conVal ); printf( "'\n" ); return ((cons > 255) ? (offset + 3) : (offset + 2)); } static int simpleInstruction( const char* name, int offset ) { printf( "%s\n", name ); return offset + 1; } int disassembleInstruction( Chunk* chunk, int offset ) { printf( "0x%08x ", offset ); if ( chunk->bDebug ) { if ( offset > 0 && chunk->lines[offset] == chunk->lines[offset - 1] ) { printf( " | " ); } else { printf( "%04d ", chunk->lines[offset] ); } } uint8_t instruction = chunk->code[offset]; switch ( instruction ) { case OP_CONSTANT: case OP_CONSTANT_LONG: return constantInstruction( "OP_CONSTANT", chunk, offset ); case OP_ADD: return simpleInstruction( "OP_ADD", offset ); case OP_SUBTRACT: return simpleInstruction( "OP_SUBTRACT", offset ); case OP_MULTIPLY: return simpleInstruction( "OP_MULTIPLY", offset ); case OP_DIVIDE: return simpleInstruction( "OP_DIVIDE", offset ); case OP_NEGATE: return simpleInstruction( "OP_NEGATE", offset ); case OP_RETURN: return simpleInstruction( "OP_RETURN", offset ); default: printf( "UNK OP %d\n", instruction ); return offset + 1; } }