/// <summary>
        ///		Optimizes the given byte code instruction list.
        /// </summary>
        /// <param name="instructionList">Instruction list to optimize.</param>
        /// <param name="symbolList">List of symbols referenced by the instruction list.</param>
        public void Optimize(ArrayList instructionList, ArrayList symbolList)
        {
            // Store and reset variables for future use.
            _instructionList = instructionList;
            _symbolList = symbolList;
            _totalOptimizationCount = 0;

            // Go through byte code instruction list in until it has been
            // optimized to the best it can be.
            while (true)
            {
                _currentInstruction = null;
                _instructionIndex = 0;
                _optimizationCount = 0;

                while (!EndOfInstructionStream())
                    OptimizeInstruction();

                _totalOptimizationCount += _optimizationCount;

                if (_optimizationCount == 0)
                    break;
            }

            // Remove all NOP's.
        }
 /// <summary>
 ///		Creates a new direct stack index operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="stackIndex">Index of stack slot this operand should point to.</param>
 /// <param name="register">Register containing index offset.</param>
 /// <returns>New operand instance.</returns>
 public static Operand DirectStackIndexedOperand(Instruction instruction, int stackIndex, Register regiser)
 {
     Operand op = new Operand(instruction, OperandType.DirectStackIndexed);
     op.StackIndex = stackIndex;
     op.OffsetRegister = regiser;
     return op;
 }
 /// <summary>
 ///		Creates a new direct memory operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="memoryIndex">Index of memory slot this operand should point to.</param>
 /// <returns>New operand instance.</returns>
 public static Operand DirectMemoryOperand(Instruction instruction, int memoryIndex)
 {
     Operand op = new Operand(instruction, OperandType.DirectMemory);
     op.MemoryIndex = memoryIndex;
     return op;
 }
 public Operand(Instruction instruction, Symbol symbol)
 {
     _opType = OperandType.SymbolIndexTracker;
     _symbolIndexTracker = symbol;
     instruction[instruction.OperandCount] = this;
 }
 public Operand(Instruction instruction, JumpTargetSymbol value)
 {
     _opType = OperandType.JumpTarget;
     _jumpTarget = value;
     instruction[instruction.OperandCount] = this;
 }
 /// <summary>
 ///		Returns the next instruction in the list and advances the stream.
 /// </summary>
 /// <returns>Next instruction in the list.</returns>
 private Instruction NextInstruction()
 {
     if (EndOfInstructionStream() == true) return null;
     _currentInstruction = (Instruction)_instructionList[_instructionIndex];
     _instructionIndex++;
     return _currentInstruction;
 }
 /// <summary>
 ///		Creates a new symbol index operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="symbolIndex">Index of symbol this operand should point to.</param>
 /// <returns>New operand instance.</returns>
 public static Operand SymbolIndexOperand(Instruction instruction, int symbolIndex)
 {
     Operand op = new Operand(instruction, OperandType.SymbolIndex);
     op.SymbolIndex = symbolIndex;
     return op;
 }
 /// <summary>
 ///		Creates a new indirect stack operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="register">Register containing stack slot this operand should point to.</param>
 /// <returns>New operand instance.</returns>
 public static Operand IndirectStackOperand(Instruction instruction, Register register)
 {
     Operand op = new Operand(instruction, OperandType.IndirectStack);
     op.Register = register;
     return op;
 }
 public Operand(Instruction instruction, double value)
 {
     _opType = OperandType.DoubleLiteral;
     _doubleLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 public Operand(Instruction instruction, int value)
 {
     _opType = OperandType.IntegerLiteral;
     _integerLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 public Operand(Instruction instruction, float value)
 {
     _opType = OperandType.FloatLiteral;
     _floatLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 public Operand(Instruction instruction, byte value)
 {
     _opType = OperandType.ByteLiteral;
     _byteLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 public Operand(Instruction instruction, bool value)
 {
     _opType = OperandType.BooleanLiteral;
     _booleanLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 /// <summary>
 ///		Initializes a new Operand instance with the given instruction as a parent
 ///		and a given operand type.
 /// </summary>
 /// <param name="instruction">Instruction this operand is associated with.</param>
 /// <param name="opType">Operand type describing what value this operand holds.</param>
 public Operand(Instruction instruction, OperandType opType)
 {
     _opType = opType;
     instruction[instruction.OperandCount] = this;
 }
 /// <summary>
 ///		Creates a new direct stack operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="stackIndex">Index of stack slot this operand should point to.</param>
 /// <returns>New operand instance.</returns>
 public static Operand DirectStackOperand(Instruction instruction, int stackIndex)
 {
     Operand op = new Operand(instruction, OperandType.DirectStack);
     op.StackIndex = stackIndex;
     return op;
 }
 public Operand(Instruction instruction, short value)
 {
     _opType = OperandType.ShortLiteral;
     _shortLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 /// <summary>
 ///		Creates a new indirect stack indexed operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="register">Register containing stack slot this operand should point to.</param>
 /// <param name="offsetRegister">Register containing index offset this operand should point to.</param>
 /// <returns>New operand instance.</returns>
 public static Operand IndirectStackIndexedOperand(Instruction instruction, Register register, Register offsetRegister)
 {
     Operand op = new Operand(instruction, OperandType.IndirectStackIndexed);
     op.Register = register;
     op.OffsetRegister = offsetRegister;
     return op;
 }
 public Operand(Instruction instruction, string value)
 {
     _opType = OperandType.StringLiteral;
     _stringLiteral = value;
     instruction[instruction.OperandCount] = this;
 }
 /// <summary>
 ///		Creates a new instruction index operand.
 /// </summary>
 /// <param name="instruction">Instruction to add operand to.</param>
 /// <param name="instrIndex">Index of instruction this operand should point to.</param>
 /// <returns>New operand instance.</returns>
 public static Operand InstrIndexOperand(Instruction instruction, int instrIndex)
 {
     Operand op = new Operand(instruction, OperandType.InstrIndex);
     op.InstrIndex = instrIndex;
     return op;
 }
 public Operand(Instruction instruction, Register value)
 {
     _opType = OperandType.Register;
     _register = value;
     instruction[instruction.OperandCount] = this;
 }
 /// <summary>
 ///		Adds an instruction to this symbols scope.
 /// </summary>
 /// <param name="instruction">Instruction to add to this symbols scope.</param>
 public void AddInstruction(Instruction instruction)
 {
     _instructionList.Add(instruction);
 }
        /// <summary>
        ///		Inserts the given instruction at the given index.
        /// </summary>
        /// <param name="index">Index to insert instruction at.</param>
        /// <param name="insertInstruction">Instruction to insert.</param>
        private void InsertInstruction(int index, Instruction insertInstruction)
        {
            // Update the instruction index's of the instruction index operands.
            foreach (Instruction instruction in _instructionList)
                for (int i = 0; i < instruction.OperandCount; i++)
                {
                    Operand operand = instruction[i];
                    if (operand.OpType == OperandType.InstrIndex && operand.InstrIndex > index)
                        operand.InstrIndex++;
                }

            // Update the entry points of the functions.
            foreach (Symbol symbol in _symbolList)
                if (symbol.Type == SymbolType.Function)
                {
                    FunctionSymbol functionSymbol = (FunctionSymbol)symbol;
                    if (functionSymbol.EntryPoint > index && functionSymbol.IsImport == false)
                        functionSymbol.EntryPoint++;
                }

            _instructionList.Insert(index, insertInstruction);
            _instructionIndex += 1;
        }