#pragma once
#include "instruction_map.hpp"

/** This utility convert Instruction to string.*/
class InstructionOutput
{
protected:
	Instruction::shared_ptr instr;
public:
	InstructionOutput()
	{
	}
	InstructionOutput(Instruction::shared_ptr instruction)
			:instr(instruction)
	{
	}
	void setInstruction(Instruction::shared_ptr instruction)
	{
		instr = instruction;
	}
	std::string parameterString()const;
	std::string bytecodeString()const;
	
	virtual void display(std::ostream& os)const;
	friend std::ostream& operator<<(
			std::ostream& os, const InstructionOutput& rh)
	{
		rh.display(os);
		return os;
	}
};
class InstructionBytecodeOutput : public InstructionOutput
{
public:
	InstructionBytecodeOutput(Instruction::shared_ptr instruction)
			:InstructionOutput(instruction)
	{
	}
	virtual void display(std::ostream& os)const
	{
		os << bytecodeString();
	}
};

class InstructionQuadrupleOutput : public InstructionOutput
{
public:
	InstructionQuadrupleOutput(Instruction::shared_ptr instruction)
			:InstructionOutput(instruction)
	{
	}
	std::string operandString(const Operand& operand)const;
	const char* operationString()const;	
	std::string quadrupleString()const;
	std::string quadrupleStringJump()const;
	virtual void display(std::ostream& os)const;
	
};
