private ICollection<AddressableInstruction> ParseSource()
{
InstructionFactory instructionParser = new InstructionFactory();
// We parse the source and build a list of all source
// instructions (including comments), and a dictionary
// of executable instructions, indexed by their source
// starting address.
List<Instruction> sourceList = new List<Instruction>();
Dictionary<int, AddressableInstruction> instructionDictionary = new Dictionary<int, AddressableInstruction>();
Dictionary<String, AddressableInstruction> labeledInstructionDictionary = new Dictionary<string, AddressableInstruction>();
int instructionSourceAddress = 0;
int instructionSourceLineNumber = 0;
// Loop through each line of source code and create an instruction for it.
foreach (String sourceLine in _sourceCodeLines)
{
Instruction sourceInstruction = instructionParser.GenerateInstruction(sourceLine, instructionSourceLineNumber, instructionSourceAddress);
if (sourceInstruction != null)
{
AddressableInstruction addressableInstruction = sourceInstruction as AddressableInstruction;
if (addressableInstruction != null)
{
instructionDictionary.Add(instructionSourceAddress, addressableInstruction);
// If the instruction has a label, store a mapping so we can resolve labeled branches later.
if (!String.IsNullOrEmpty(addressableInstruction.Address.AddressLabel))
{
labeledInstructionDictionary.Add(addressableInstruction.Address.AddressLabel, addressableInstruction);
}
instructionSourceAddress += addressableInstruction.SourceLength;
}
sourceList.Add(sourceInstruction);
instructionSourceLineNumber++;
}
}
// Loop through each instruction and map each branch address to the destination instruction.
// This is done at the source level at this stage so we have a correctly mapped instruction
// tree before we start generating binary and create the actual addresses.
foreach (var instruction in instructionDictionary)
{
IBranchingInstruction branchingInstruction = instruction.Value as IBranchingInstruction;
if (branchingInstruction != null)
{
branchingInstruction.MapBranchAddress(instructionDictionary, labeledInstructionDictionary);
}
IAddressedOperands addressedOperandsInstruction = instruction.Value as IAddressedOperands;
if (addressedOperandsInstruction != null)
{
addressedOperandsInstruction.MapAddressedOperands(instructionDictionary, labeledInstructionDictionary);
}
AddressableMemoryInstruction memoryValue = instruction.Value as AddressableMemoryInstruction;
if (memoryValue != null)
{
memoryValue.MapMemoryValue(instructionDictionary, labeledInstructionDictionary);
}
}
return instructionDictionary.Values;
}