private void readInstructions()
        {
            // Create array for instructions
            this.Instructions = new LuaInstruction[this.instructionCount];
            // Go through all instructions
            for (int i = 0; i < this.instructionCount; i++)
            {
                // Making a new instruction
                LuaInstruction instruction = new LuaInstruction(this);
                // Reading the values attached to the instruction
                // A = 8 bits
                // B = 9 bits
                // C = 8 bits
                // OpCode = 7 bits
                instruction.A = this.inputReader.ReadByte();

                int  cValue = this.inputReader.ReadByte();
                byte bValue = this.inputReader.ReadByte();
                if (GetBit(bValue, 0) == 1)
                {
                    cValue += 256;
                }
                instruction.C = cValue;

                instruction.B = bValue >> 1;
                byte flagsB = this.inputReader.ReadByte();
                if (GetBit(flagsB, 0) == 1)
                {
                    instruction.B += 128;
                }

                instruction.Bx  = (instruction.B * 512) + instruction.C;
                instruction.sBx = instruction.Bx - 65536 + 1;

                if (this.luaFile.OPCodeTable.TryGetValue(flagsB >> 1, out LuaOpCode.OpCodes opcode))
                {
                    instruction.OpCode = opcode;
                }
                else
                {
                    instruction.OpCode = LuaOpCode.OpCodes.HKS_OPCODE_UNK;
                }

                // Add to array
                this.Instructions[i] = instruction;
            }
        }
        public string BuildExpression(LuaCondition masterCondition)
        {
            string Expression = ProcessInstructionReturnString();

            nextInstruction();
            int ChildExpressions = 0;

            foreach (LuaCondition condition in this.conditions)
            {
                if (condition.master == masterCondition)
                {
                    ChildExpressions++;
                }
            }
            while (ChildExpressions > 0 && this.instructionPtr < this.instructionCount)
            {
                bool done = false;
                currentInstruction = this.Instructions[instructionPtr];
                foreach (LuaCondition condition in this.conditions)
                {
                    if (condition.master == masterCondition && condition.line == this.instructionPtr)
                    {
                        Expression += String.Format(" {0} ", condition.prefix);
                        Expression += ProcessInstructionReturnString();
                        ChildExpressions--;
                        done = true;
                    }
                }
                if (!done)
                {
                    ProcessInstructionReturnString();
                }
                nextInstruction();
            }
            return(Expression);
        }
        public void decompile(int tabLevel = 0, bool inline = false)
        {
#if DEBUG
            this.writeLine(String.Format("-- OP Count: 0x{0:X}", this.instructionCount));
            this.writeLine(String.Format("-- Constant Count: 0x{0:X}", this.constantCount));
            this.writeLine(String.Format("-- Registers Count: 0x{0:X}", this.registerCount));
            this.writeLine(String.Format("-- UpValue Count: 0x{0:X}", this.upValsCount));
            this.writeLine(String.Format("-- SubFuncs Count: 0x{0:X}", this.subFunctionCount));
#endif

            FindWhileLoops();
            FindDoWhileLoops();
            FindIfStatements();
            FindForEachLoops();

            for (int i = 0; i < this.instructionCount; i++)
            {
                this.Instructions[i].visited = false;
            }

            this.tabLevel  = tabLevel;
            this.Registers = new LuaRegister[this.registerCount];
            for (int i = 0; i < this.registerCount; i++)
            {
                this.Registers[i] = new LuaRegister(i);
            }

            // Write the function header if it isnt the init function
            if (!this.isInitFunction)
            {
                // Look if we have a inline function
                if (inline)
                {
                    outputWriter.Write("function (");
                }
                else if (this.newName == null)
                {
                    write("local function " + String.Format("__FUNC_{0:X}_", this.startPosition) + "(", -1);
                }
                else
                {
                    write("function " + this.newName + "(", -1);
                }
                int argIndex = 0, fixedIndex = 0;
                while (argIndex < this.parameterCount)
                {
                    if (this.Upvalues.Contains("arg" + fixedIndex))
                    {
                        fixedIndex++;
                        continue;
                    }
                    this.Registers[argIndex].initialze("arg" + fixedIndex);
                    outputWriter.Write(((argIndex > 0) ? ", " : "") + "arg" + fixedIndex++);
                    argIndex++;
                }
                if (this.usesVarArg)
                {
                    if (this.parameterCount > 0)
                    {
                        outputWriter.Write(", ");
                    }
                    outputWriter.Write("...");
                }
                outputWriter.Write(")\n");
            }

            this.instructionPtr = 0;
            while (this.instructionPtr < this.instructionCount)
            {
                try
                {
                    currentInstruction = this.Instructions[instructionPtr];

                    if (HasCondition() || currentInstruction.visited == true)
                    {
                        nextInstruction();
                        continue;
                    }
                    if (LuaOpCode.OPCodeFunctions.TryGetValue(currentInstruction.OpCode, out Func <LuaFunction, string> func))
                    {
                        func(this);
                    }
                    else
                    {
                        this.writeLine(String.Format("Unhandled OpCode: {0} ({1}, {2}, {3}, 0x{4:X})",
                                                     currentInstruction.OpCode,
                                                     currentInstruction.A,
                                                     currentInstruction.B,
                                                     currentInstruction.C,
                                                     (int)currentInstruction.OpCode));
                    }
                    foreach (LuaCondition condition in this.conditions)
                    {
                        if (condition.line == this.instructionPtr)
                        {
                            if (condition.type == LuaCondition.Type.End)
                            {
                                this.tabLevel--;
                                this.writeLine("end");
                            }
                            else if (condition.type == LuaCondition.Type.Else)
                            {
                                this.writeLine("else", -1);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error @ " + this.instructionPtr + ": " + e.Message + " & " + this.Instructions[instructionPtr].OpCode);
                }
                nextInstruction();
            }

            // Add an ending to the function
            if (!this.isInitFunction)
            {
                writeLine("end", -1);
                this.outputWriter.WriteLine();
            }
        }