1 using System;
  2 using System.IO;
  3 using System.Collections;
  4 using CodeFormatter = System.Text.CodeFormatter;
  5 
  6 namespace cmsx.intermediate
  7 {
  8     public const int separatorInstructionOpCode = -1;
  9 
 10     public class MachineInstruction
 11     {
 12         public nothrow MachineInstruction(int opCode_) : opCode(opCode_)
 13         {
 14         }
 15         public nothrow void SetLabel(const string& label_)
 16         {
 17             label = label_;
 18         }
 19         public nothrow void AddOperand(Operand* operand)
 20         {
 21             operands.Add(operand);
 22         }
 23         public nothrow void Print(CodeFormatter& formatterint labelWidth)
 24         {
 25             if (opCode == separatorInstructionOpCode) return;
 26             formatter << Format(labellabelWidthFormatWidth.min) << " " << Format(cmsx.assembly.GetOpCodeStr(opCode)
 27                 Max(cmsx.machine.OpCodeMap.Instance().MaxOpCodeNameLength()cmsx.assembly.PseudoOpMap.Instance().MaxOpCodeNameLength())FormatWidth.min) << " ";
 28             long n = operands.Count();
 29             for (long i = 0; i < n; ++i;)
 30             {
 31                 if (i > 0)
 32                 {
 33                     formatter << ",";
 34                 }
 35                 Operand* operand = operands[i];
 36                 operand->Print(formatter);
 37             }
 38         }
 39         private string label;
 40         private int opCode;
 41         private List<Operand*> operands;
 42     }
 43 
 44     public class MachineCode
 45     {
 46         public nothrow MachineCode(Context& context_) : context(context_)prevInst(null)
 47         {
 48         }
 49         public inline nothrow long CurrentIndex() const
 50         {
 51             return machineInstructions.Count();
 52         }
 53         public nothrow MachineInstruction* GetInstruction(int opCodeconst string& label)
 54         {
 55             MachineInstruction* inst = GetInstruction(opCodenull);
 56             inst->SetLabel(label);
 57             return inst;
 58         }
 59         public nothrow MachineInstruction* GetInstruction(int opCodeInstruction* inst)
 60         {
 61             MachineInstruction* machineInstruction = new MachineInstruction(opCode);
 62             if (inst != null && inst != prevInst && inst->IsLeader())
 63             {
 64                 machineInstruction->SetLabel(inst->parent->Name());
 65                 prevInst = inst;
 66             }
 67             machineInstructions.Add(UniquePtr<MachineInstruction>(machineInstruction));
 68             return machineInstruction;
 69         }
 70         public nothrow void EmitLineNumberInfo()
 71         {
 72             MachineInstruction* bspecInst = GetInstruction(cmsx.assembly.BSPECnull);
 73             MachineInstruction* octaInst = GetInstruction(cmsx.assembly.OCTAnull);
 74             octaInst->AddOperand(context.GetLiteralOperand(cmsx.assembly.LINEINFO));
 75             octaInst->AddOperand(context.GetLiteralOperand(currentLineNumber));
 76             MachineInstruction* especInst = GetInstruction(cmsx.assembly.ESPECnull);
 77         }
 78         public nothrow void PrintRange(long startIndexlong endIndexCodeFormatter& formatter)
 79         {
 80             PrintRange(startIndexendIndexformatter6);
 81         }
 82         public nothrow void PrintRange(long startIndexlong endIndexCodeFormatter& formatterint labelWidth)
 83         {
 84             for (long i = startIndex; i < endIndex; ++i;)
 85             {
 86                 MachineInstruction* inst = machineInstructions[i].Get();
 87                 inst->Print(formatterlabelWidth);
 88                 formatter.WriteLine();
 89             }
 90         }
 91         public nothrow void Print(CodeFormatter& formatter)
 92         {
 93             PrintRange(0machineInstructions.Count()formatter80);
 94         }
 95         public nothrow void Print(const string& filePath)
 96         {
 97             StreamWriter writer = File.CreateText(filePath);
 98             CodeFormatter formatter(writer);
 99             Print(formatter);
100         }
101         public Context& context;
102         public uint currentLineNumber;
103         private List<UniquePtr<MachineInstruction>> machineInstructions;
104         private Instruction* prevInst;
105     }
106 }