Пример #1
0
        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);
        }