private static int byteInstruction(string name, ref Chunk_t chunk, int offset) { byte slot = chunk.code[offset + 1]; System.Console.WriteLine("{0,-16}{1,4}", name, slot.ToString()); return(offset + 2); }
private static int jumpInstruction(string name, int sign, ref Chunk_t chunk, int offset) { ushort jump = (ushort)(chunk.code[offset + 1] << 8); jump |= (ushort)chunk.code[offset + 2]; System.Console.WriteLine("{0,-16}{1,4} -> {2}", name, offset.ToString(), (offset + 3 + sign * jump).ToString()); return(offset + 3); }
public static void disassembleChunk(ref Chunk_t chunk, char[] name) { System.Console.WriteLine("== {0} ==", new string(name, 0, name.Length - 1)); for (int offset = 0; offset < chunk.count;) { offset = disassembleInstruction(ref chunk, offset); } }
private static int constantInstruction(string name, ref Chunk_t chunk, int offset) { byte constant = chunk.code[offset + 1]; System.Console.Write("{0,-16} {1,4} '", name, constant.ToString()); Value.printValue(chunk.constants.values[constant]); System.Console.WriteLine("'"); return(offset + 2); }
private static int invokeInstruction(string name, ref Chunk_t chunk, int offset) { byte constant = chunk.code[offset + 1]; byte argCount = chunk.code[offset + 2]; System.Console.Write("{0,-16} ({1} args) {2,4} '", name, argCount.ToString(), constant.ToString()); Value.printValue(chunk.constants.values[constant]); System.Console.WriteLine(); return(offset + 3); }
public static int disassembleInstruction(ref Chunk_t chunk, int offset) { System.Console.Write("{0} ", offset.ToString("D4")); if (offset > 0 && chunk.lines[offset] == chunk.lines[offset - 1]) { System.Console.Write(" | "); } else { System.Console.Write("{0,4} ", chunk.lines[offset].ToString()); } OpCode instruction = (OpCode)chunk.code[offset]; switch (instruction) { case OpCode.OP_CONSTANT: return(constantInstruction("OP_CONSTANT", ref chunk, offset)); case OpCode.OP_NIL: return(simpleInstruction("OP_NIL", offset)); case OpCode.OP_TRUE: return(simpleInstruction("OP_TRUE", offset)); case OpCode.OP_FALSE: return(simpleInstruction("OP_FALSE", offset)); case OpCode.OP_POP: return(simpleInstruction("OP_POP", offset)); case OpCode.OP_GET_LOCAL: return(byteInstruction("OP_GET_LOCAL", ref chunk, offset)); case OpCode.OP_SET_LOCAL: return(byteInstruction("OP_SET_LOCAL", ref chunk, offset)); case OpCode.OP_GET_GLOBAL: return(constantInstruction("OP_GET_GLOBAL", ref chunk, offset)); case OpCode.OP_DEFINE_GLOBAL: return(constantInstruction("OP_DEFINE_GLOBAL", ref chunk, offset)); case OpCode.OP_SET_GLOBAL: return(constantInstruction("OP_SET_GLOBAL", ref chunk, offset)); case OpCode.OP_GET_UPVALUE: return(byteInstruction("OP_GET_UPVALUE", ref chunk, offset)); case OpCode.OP_SET_UPVALUE: return(byteInstruction("OP_SET_UPVALUE", ref chunk, offset)); case OpCode.OP_GET_PROPERTY: return(constantInstruction("OP_GET_PROPERTY", ref chunk, offset)); case OpCode.OP_SET_PROPERTY: return(constantInstruction("OP_SET_PROPERTY", ref chunk, offset)); case OpCode.OP_GET_SUPER: return(constantInstruction("OP_GET_SUPER", ref chunk, offset)); case OpCode.OP_EQUAL: return(simpleInstruction("OP_EQUAL", offset)); case OpCode.OP_GREATER: return(simpleInstruction("OP_GREATER", offset)); case OpCode.OP_LESS: return(simpleInstruction("OP_LESS", offset)); case OpCode.OP_ADD: return(simpleInstruction("OP_ADD", offset)); case OpCode.OP_SUBTRACT: return(simpleInstruction("OP_SUBTRACT", offset)); case OpCode.OP_MULTIPLY: return(simpleInstruction("OP_MULTIPLY", offset)); case OpCode.OP_DIVIDE: return(simpleInstruction("OP_DIVIDE", offset)); case OpCode.OP_NOT: return(simpleInstruction("OP_NOT", offset)); case OpCode.OP_NEGATE: return(simpleInstruction("OP_NEGATE", offset)); case OpCode.OP_PRINT: return(simpleInstruction("OP_PRINT", offset)); case OpCode.OP_JUMP: return(jumpInstruction("OP_JUMP", 1, ref chunk, offset)); case OpCode.OP_JUMP_IF_FALSE: return(jumpInstruction("OP_JUMP_IF_FALSE", 1, ref chunk, offset)); case OpCode.OP_LOOP: return(jumpInstruction("OP_LOOP", -1, ref chunk, offset)); case OpCode.OP_CALL: return(byteInstruction("OP_CALL", ref chunk, offset)); case OpCode.OP_INVOKE: return(invokeInstruction("OP_INVOKE", ref chunk, offset)); case OpCode.OP_SUPER_INVOKE: return(invokeInstruction("OP_SUPER_INVOKE", ref chunk, offset)); case OpCode.OP_CLOSURE: { offset++; byte constant = chunk.code[offset++]; System.Console.Write("{0,-16} {1,4} ", "OP_CLOSURE ", constant.ToString()); Value.printValue(chunk.constants.values[constant]); System.Console.WriteLine(); ObjFunction function = Object.AS_FUNCTION(chunk.constants.values[constant]); for (int j = 0; j < function.upvalueCount; j++) { int isLocal = chunk.code[offset++]; int index = chunk.code[offset++]; System.Console.WriteLine("{0} | {1} {2}", (offset - 2).ToString("D4"), ((isLocal != 0) ? "local" : "upvalue"), index.ToString()); } return(offset); } case OpCode.OP_CLOSE_UPVALUE: return(simpleInstruction("OP_CLOSE_UPVALUE", offset)); case OpCode.OP_RETURN: return(simpleInstruction("OP_RETURN", offset)); case OpCode.OP_CLASS: return(constantInstruction("OP_CLASS", ref chunk, offset)); case OpCode.OP_INHERIT: return(simpleInstruction("OP_INHERIT", offset)); case OpCode.OP_METHOD: return(constantInstruction("OP_METHOD", ref chunk, offset)); default: System.Console.WriteLine("Unkown opcode " + ((byte)instruction).ToString()); return(offset + 1); } }