Esempio n. 1
0
        string DumpCodeBlock(Function func, Stack<string> stack, CodeBlock block, ref string pre)
        {
            string res = pre + "{\r\n";
            pre += "    ";
            Dictionary<int, List<string>> switchTargets = null;
            int startIndex = func.Instructions.IndexOf(block.Instructions[0]);
            int endIndex = block.EndIndex(func);
            int branch = 0;
            bool switchStarted = false;
            bool elseStarted = false;
            foreach (Instruction i in block.Instructions)
            {
                if (i.IsBranchTarget && (i.BranchFrom > func.Instructions.IndexOf(i)) && !block.Instructions.Contains(func.Instructions[i.BranchFrom]))
                {
                    int index = func.Instructions.IndexOf(i);
                    res += pre + "label" + index + ":\r\n";
                }
                if (i.Inst == Instructions.DummyCodeBlock)
                {
                    if (switchTargets != null)
                    {
                        CodeBlock tar = block.CodeBlocks[i.Operand1];
                        int index = func.Instructions.IndexOf(tar.Instructions[0]);
                        if (switchTargets.ContainsKey(index))
                        {
                            if (switchStarted)
                            {
                                res += pre + "break;\r\n";
                                pre = pre.Substring(4);
                            }
                            foreach (string j in switchTargets[index])
                            {
                                if (j != "default")
                                    res += string.Format("{0}case {1}:\r\n", pre, j);
                                else
                                    res += string.Format("{0}{1}:\r\n", pre, j);
                            }
                            switchStarted = true;
                        }
                        else
                            pre = pre.Substring(4);
                    }
                    if (switchTargets != null)
                        pre += "    ";
                    if (elseStarted && branch > 0)
                    {
                        res += pre + "else\r\n" + pre + "{\r\n";
                        pre += "    ";
                    }

                    int stackOld = stack.Count;
                    string cont = DumpCodeBlock(func, stack, block.CodeBlocks[i.Operand1], ref pre);
                    res += cont;
                    if (stack.Count > stackOld)
                    {
                        if (branch > 0)
                        {
                            if (!elseStarted)
                            {
                                Variable newVar = new Variable();
                                newVar.VarType = VarTypes.Unknown;
                                newVar.Name = "v" + func.LocalVariables.Count;
                                func.LocalVariables.Add(newVar);
                                res += pre + newVar.Name + " = " + stack.Pop() + ";\r\n";
                                elseStarted = true;
                                pre = pre.Substring(4);
                                res += pre + "}\r\n";
                                stack.Push(newVar.Name);
                                continue;
                            }
                            else
                            {
                                Variable newVar = func.LocalVariables[func.LocalVariables.Count - 1];
                                res += pre + newVar.Name + " = " + stack.Pop() + ";\r\n";
                                if (stack.Count == 0 || stack.Peek() != newVar.Name)
                                    stack.Push(newVar.Name);
                            }
                        }
                        else
                        {

                        }
                    }
                    else
                    {
                        if (branch > 0 && !elseStarted)
                        {
                            elseStarted = i.Operand2 == 0;
                            if (i.Operand2 == 1)
                                branch--;
                            pre = pre.Substring(4);
                            res += pre + "}\r\n";
                            continue;
                        }
                    }
                    if (switchTargets != null && !switchStarted)
                        pre = pre.Substring(4);
                    if (elseStarted && branch > 0)
                    {
                        pre = pre.Substring(4);
                        res += pre + "}\r\n";
                        branch--;
                    }
                }
                else
                {
                    switch (i.Inst)
                    {
                        case Instructions.Push:
                            {
                                if (i.Operand1 == -1)
                                    stack.Push("null");
                                else
                                    stack.Push(i.Operand1.ToString());
                            }
                            break;
                        case Instructions.Pop:
                            {
                                string content = stack.Pop();
                                if (content.StartsWith("call "))
                                    res += pre + content.Replace("call ", "") + ";\r\n";
                            }
                            break;
                        case Instructions.Ref:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.PushGP:
                            {
                                stack.Push("GlobalPage");
                            }
                            break;
                        case Instructions.PushLP:
                            {
                                stack.Push("LocalPage");
                            }
                            break;
                        case Instructions.Inv:
                        case Instructions.NegF:
                            {
                                stack.Push("-" + ProcessCondition(stack.Pop()));
                            }
                            break;
                        case Instructions.Not:
                            {
                                stack.Push("!" + ProcessCondition(stack.Pop()));
                            }
                            break;
                        case Instructions.NotBit:
                            {
                                stack.Push("~" + ProcessCondition(stack.Pop()));
                            }
                            break;
                        case Instructions.Add:
                        case Instructions.AddF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " + " + op1 + ")");
                            }
                            break;
                        case Instructions.Min:
                        case Instructions.MinF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " - " + op1 + ")");
                            }
                            break;
                        case Instructions.Mul:
                        case Instructions.MulF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " * " + op1 + ")");
                            }
                            break;
                        case Instructions.Div:
                        case Instructions.DivF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " / " + op1 + ")");
                            }
                            break;
                        case Instructions.Mod:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " % " + op1 + ")");
                            }
                            break;
                        case Instructions.And:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " & " + op1 + ")");
                            }
                            break;
                        case Instructions.Or:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " | " + op1 + ")");
                            }
                            break;
                        case Instructions.Xor:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " ^ " + op1 + ")");
                            }
                            break;
                        case Instructions.Shl:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " << " + op1 + ")");
                            }
                            break;
                        case Instructions.Shr:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " >> " + op1 + ")");
                            }
                            break;
                        case Instructions.Le:
                        case Instructions.LeF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " < " + op1 + ")");
                            }
                            break;
                        case Instructions.Ge:
                        case Instructions.GeF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " > " + op1 + ")");
                            }
                            break;
                        case Instructions.Leq:
                        case Instructions.LeqF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " <= " + op1 + ")");
                            }
                            break;
                        case Instructions.Geq:
                        case Instructions.GeqF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " >= " + op1 + ")");
                            }
                            break;
                        case Instructions.Neq:
                        case Instructions.NeqF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " != " + op1 + ")");
                            }
                            break;
                        case Instructions.Eql:
                        case Instructions.EqlF:
                            {
                                string op1 = ProcessCondition(stack.Pop());
                                string op2 = ProcessCondition(stack.Pop());
                                stack.Push("(" + op2 + " == " + op1 + ")");
                            }
                            break;
                        case Instructions.Assign:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} = {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.AddA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} += {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.MinA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} -= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.MulA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} *= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.DivA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} /= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.ModA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} %= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.AndA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} &= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.OrA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} |= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.ShlA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} <<= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.ShrA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} >>= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(string.Format("{0}", refObj));
                            }
                            break;
                        case Instructions.AssignF:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} = {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.AddFA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} += {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.MinFA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} -= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.MulFA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} *= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.DivFA:
                            {
                                string val = stack.Pop();
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} /= {2};\r\n", pre, refObj, ProcessCondition(val));
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.Dup2:
                            {
                                string v1 = stack.Pop();
                                string v2 = stack.Pop();
                                stack.Push(v2);
                                stack.Push(v1);
                                stack.Push(v2);
                                stack.Push(v1);
                            }
                            break;
                        case Instructions.Dup_At3:
                            {
                                string v3 = stack.Pop();
                                string v2 = stack.Pop();
                                string v1 = stack.Pop();
                                stack.Push(v3);
                                stack.Push(v1);
                                stack.Push(v2);
                                stack.Push(v3);
                            }
                            break;
                        case Instructions.Jmp:
                            {
                                if (i.BranchTarget[0] == startIndex)
                                {
                                    if (branch == 0)
                                    {
                                        string pre2 = pre.Substring(0, pre.Length - 4);
                                        res = pre2 + "while(true)\r\n" + res;
                                    }
                                    else
                                    {
                                        string[] token = res.Split('\n');
                                        res = "";
                                        for (int j = 0; j < token.Length - 3; j++)
                                        {
                                            res += token[j] + "\n";
                                        }
                                        pre = pre.Substring(0, pre.Length - 4);
                                        string pre2 = pre.Substring(0, pre.Length - 4);
                                        res = string.Format("{1}while{0}\n", token[token.Length - 3].TrimStart(' ').Replace("if", ""), pre2) + res;
                                        branch--;
                                    }
                                }
                                else
                                {
                                    if (switchStarted)
                                    {
                                        res += pre + "break;\r\n";
                                        pre = pre.Substring(4);
                                    }
                                    if (i.BranchTarget[0] < endIndex)
                                    {
                                        res += string.Format("{0}jmp label{1};\r\n", pre, i.BranchTarget[0]);
                                    }
                                    else
                                    {
                                        if (branch > 0 || block.Instructions.Count ==1)
                                        {
                                            res += string.Format("{0}jmp label{1};\r\n", pre, i.BranchTarget[0]);
                                            if (branch > 0)
                                            {
                                                pre = pre.Substring(4);
                                                res += pre + "}\r\n";
                                                branch--;
                                            }
                                        }
                                        else
                                        {
                                        }
                                    }
                                }
                            }
                            break;
                        case Instructions.BrFalse:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                string cond = stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name;
                                res += pre + string.Format("if({0})\r\n", ProcessCondition(cond));
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BrTrue:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                string cond = stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name;
                                res += pre + string.Format("if(!({0}))\r\n", ProcessCondition(cond));
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.Ret:
                            {
                                if (func.ReturnType != VarTypes.Void)
                                    res += pre + "return " + ProcessCondition(stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name) + ";\r\n";
                                else
                                    res += pre + "return;\r\n";
                                if (branch > 0)
                                {
                                    pre = pre.Substring(4);
                                    res += pre + "}\r\n";
                                }
                            }
                            break;
                        case Instructions.Call:
                        case Instructions.CallMethod:
                        case Instructions.CallDelegate:
                            {
                                string cmd = "";
                                Function tar = null;
                                string refe = "";
                                if (i.Inst != Instructions.CallDelegate)
                                    tar = this.func[i.Operand1];
                                else
                                {
                                    int funcID;
                                    //stack.Pop();
                                    if (int.TryParse(stack.Peek(), out funcID))
                                    {
                                        tar = this.fnct[int.Parse(stack.Pop())];
                                        refe = ProcessCondition(stack.Pop());
                                    }
                                    else
                                    {
                                        stack.Pop();
                                        refe = ProcessCondition(stack.Pop());
                                        res += string.Format("{0}{1}.UnknownDelegate();\r\n", pre, refe);
                                        break;
                                    }
                                }
                                string args = "";
                                for (int j = 0; j < tar.ArgCount; j++)
                                {
                                    switch (tar.Arguments[tar.ArgCount - j - 1].VarType)
                                    {
                                        case VarTypes.IntRef:
                                        case VarTypes.FloatRef:
                                            {
                                                stack.Push("ref " + GetRef(func, stack));
                                            }
                                            break;
                                        case VarTypes.StrucRef:
                                        case VarTypes.ArrayFloatRef:
                                        case VarTypes.ArrayIntRef:
                                        case VarTypes.ArrayStringRef:
                                        case VarTypes.ArrayStructRef:
                                        case VarTypes.StringRef:
                                            {
                                                stack.Push("ref " + ProcessCondition(stack.Pop()));
                                            }
                                            break;
                                        default:
                                            break;
                                    }

                                    if (tar.Arguments[tar.ArgCount - j - 1].VarType == VarTypes.Void)
                                        continue;
                                    args = ProcessCondition(stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name) + ", " + args;
                                }
                                if (args != "")
                                    args = args.Substring(0, args.Length - 2);
                                if (i.Inst == Instructions.CallMethod)
                                    refe = stack.Pop() + ".";
                                string name = i.Inst == Instructions.CallMethod ? tar.Name.Split('@')[1] : tar.Name;
                                if (i.Inst == Instructions.CallDelegate)
                                    name = "";
                                cmd = string.Format("{2}{0}({1})", name, args, refe);
                                if (tar.ReturnType != VarTypes.Void)
                                    stack.Push("call " + cmd);
                                else
                                    res += pre + cmd + ";\r\n";
                            }
                            break;
                        case Instructions.Inc:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}++;\r\n", pre, refObj);
                            }
                            break;
                        case Instructions.Dec:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}--;\r\n", pre, refObj);
                            }
                            break;
                        case Instructions.FTOI:
                            {
                                stack.Push("((int)(" + ProcessCondition(stack.Pop()) + "))");
                            }
                            break;
                        case Instructions.ITOF:
                            {
                                stack.Push("((float)(" + ProcessCondition(stack.Pop()) + "))");
                            }
                            break;
                        case Instructions.PushF:
                            {
                                stack.Push(i.Operand1F.ToString());
                            }
                            break;
                        case Instructions.PushS:
                            {
                                stack.Push(string.Format("\"{0}\"", this.strings[i.Operand1].Replace("\n", "\\n")));
                            }
                            break;
                        case Instructions.PopStructRef:
                        case Instructions.PopS:
                            {
                                string content = stack.Pop();
                                if (content.StartsWith("call "))
                                    res += pre + content.Replace("call ", "") + ";\r\n";
                            }
                            break;
                        case Instructions.Add_S:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());
                                stack.Push(string.Format("({0} + {1})", obj1, obj2));
                            }
                            break;
                        case Instructions.AssignS:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1} = {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.PushS_Ref:
                            {
                                stack.Push(GetRef(func, stack));
                            }
                            break;
                        case Instructions.StringNeq:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());
                                stack.Push(string.Format("({0} != {1})", obj1, obj2));
                            }
                            break;
                        case Instructions.StringEql:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());
                                stack.Push(string.Format("({0} == {1})", obj1, obj2));
                            }
                            break;
                        case Instructions.AssignStructRef:
                            {
                                stack.Pop();
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1} = {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.ArrayStructRef:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("(({0}){1})", this.structs[i.Operand1].Name, refObj));
                            }
                            break;
                        case Instructions.AllocA:
                            {
                                string dimension = ProcessCondition(stack.Pop());
                                string count = "";
                                for (int j = 0; j < int.Parse(dimension); j++)
                                    count += ProcessCondition(stack.Pop()) + ", ";
                                if (count != "")
                                    count = count.Substring(0, count.Length - 2);
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.Alloc({2});\r\n", pre, refObj, count);
                            }
                            break;
                        case Instructions.ReallocA:
                            {
                                string dimension = ProcessCondition(stack.Pop());
                                string count = "";
                                for (int j = 0; j < int.Parse(dimension); j++)
                                    count += ProcessCondition(stack.Pop()) + ", ";
                                if (count != "")
                                    count = count.Substring(0, count.Length - 2);
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.Realloc({2});\r\n", pre, refObj, count);
                            }
                            break;
                        case Instructions.FreeA:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.Free();\r\n", pre, refObj);
                            }
                            break;
                        case Instructions.ArrayLength:
                            {
                                int dimension = int.Parse(stack.Pop());
                                string refObj = GetRef(func, stack);
                                if (dimension == 1)
                                {
                                    stack.Push(string.Format("{0}.Length", refObj));
                                }
                                else
                                {
                                    stack.Push(string.Format("{0}[{1}].Length", refObj, dimension));
                                }
                            }
                            break;
                        case Instructions.CopyA:
                            {
                                string count = ProcessCondition(stack.Pop());
                                string index2 = ProcessCondition(stack.Pop());
                                string a2 = ProcessCondition(stack.Pop());
                                string index1 = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.Copy({2},{3},{4},{5});\r\n", pre, refObj, index1, a2, index2, count);
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.ArrayFill:
                            {
                                string val = ProcessCondition(stack.Pop());
                                string count = ProcessCondition(stack.Pop());
                                string index = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.Fill({1},{2},{3})", refObj, index, count, val));
                            }
                            break;
                        case Instructions.CharRef:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.AssignChar:
                            {
                                string val = ProcessCondition(stack.Pop());                                
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} = {2}", pre, refObj, val);
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.Msg:
                            {
                                res += string.Format("{0}System.Message(\"{1}\");\r\n", pre, this.msgs[i.Operand1].Replace("\n", "\\n"));
                            }
                            break;
                        case Instructions.CallHLL:
                            {
                                string cmd = "";
                                Hll tar = this.hlls[i.Operand1];
                                string args = "";
                                for (int j = 0; j < tar.Functions[i.Operand2].ArgCount; j++)
                                {
                                    switch (tar.Functions[i.Operand2].Arguments[tar.Functions[i.Operand2].ArgCount - j - 1].VarType)
                                    {
                                        case VarTypes.IntRef:
                                        case VarTypes.FloatRef:
                                            {
                                                stack.Push("ref " + GetRef(func, stack));
                                            }
                                            break;
                                        case VarTypes.StrucRef:
                                        case VarTypes.ArrayFloatRef:
                                        case VarTypes.ArrayIntRef:
                                        case VarTypes.ArrayStringRef:
                                        case VarTypes.ArrayStructRef:
                                        case VarTypes.StringRef:
                                            {
                                                stack.Push("ref " + ProcessCondition(stack.Pop()));
                                            }
                                            break;
                                        default:
                                            break;
                                    }

                                    if (tar.Functions[i.Operand2].Arguments[tar.Functions[i.Operand2].ArgCount - j - 1].VarType == VarTypes.Void)
                                        continue;
                                    args = ProcessCondition(stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name) + ", " + args;
                                }
                                /*for (int j = 0; j < tar.Functions[i.Operand2].ArgCount; j++)
                                    args = ProcessCondition(stack.Pop()) + ", " + args;*/
                                if (args != "")
                                    args = args.Substring(0, args.Length - 2);
                                cmd = string.Format("{0}.{1}({2})", tar.Name, tar.Functions[i.Operand2].Name, args);
                                if (tar.Functions[i.Operand2].ReturnType != VarTypes.Void)
                                    stack.Push("call " + cmd);
                                else
                                    res += pre + cmd + ";\r\n";
                            }
                            break;
                        case Instructions.PushSP:
                            {
                                stack.Push("this");
                            }
                            break;
                        case Instructions.RefGlobal:
                            {
                                stack.Push(string.Format("Global.{0}", this.global[i.Operand1].Name));
                            }
                            break;
                        case Instructions.RefLocal:
                            {
                                stack.Push(func.LocalVariables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.Switch:
                        case Instructions.SwitchS:
                            {
                                Switch swi = this.SwitchTables[i.Operand1];
                                List<int> keys = swi.SwitchTable.Keys.ToList();
                                switchTargets = new Dictionary<int, List<string>>();
                                for (int j = 0; j < keys.Count; j++)
                                {
                                    if (!switchTargets.ContainsKey(i.BranchTarget[j]))
                                        switchTargets.Add(i.BranchTarget[j], new List<string>());
                                    if (swi.SwitchType == SwitchTypes.Integer)
                                        switchTargets[i.BranchTarget[j]].Add(keys[j].ToString());
                                    else
                                        switchTargets[i.BranchTarget[j]].Add("\"" + this.strings[keys[j]] + "\"");
                                }
                                if (swi.DefaultCase != -1)
                                {
                                    if (!switchTargets.ContainsKey(i.BranchTarget[keys.Count]))
                                        switchTargets.Add(i.BranchTarget[keys.Count], new List<string>());
                                    switchTargets[i.BranchTarget[keys.Count]].Add("default");
                                }
                                res += pre + string.Format("switch({0})\r\n", ProcessCondition(stack.Pop()));
                                res += pre + "{\r\n";
                                pre += "    ";
                            }
                            break;
                        case Instructions.CallSys:
                            {
                                string cmd = "";
                                Function tar = Function.Syscalls[(Syscalls)i.Operand1];
                                string args = "";
                                for (int j = 0; j < tar.ArgCount; j++)
                                {
                                    switch (tar.Arguments[tar.ArgCount - j - 1].VarType)
                                    {
                                        case VarTypes.IntRef:
                                        case VarTypes.FloatRef:
                                            {
                                                stack.Push("ref " + GetRef(func, stack));
                                            }
                                            break;
                                        case VarTypes.StrucRef:
                                        case VarTypes.ArrayFloatRef:
                                        case VarTypes.ArrayIntRef:
                                        case VarTypes.ArrayStringRef:
                                        case VarTypes.ArrayStructRef:
                                        case VarTypes.StringRef:
                                            {
                                                stack.Push("ref " + ProcessCondition(stack.Pop()));
                                            }
                                            break;
                                        default:
                                            break;
                                    }

                                    if (tar.Arguments[tar.ArgCount - j - 1].VarType == VarTypes.Void)
                                        continue;
                                    args = ProcessCondition(stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name) + ", " + args;
                                }
                                if (args != "")
                                    args = args.Substring(0, args.Length - 2);
                                cmd = string.Format("System.{0}({1})", tar.Name, args);
                                if (tar.ReturnType != VarTypes.Void)
                                    stack.Push("call " + cmd);
                                else
                                    res += pre + cmd + ";\r\n";
                            }
                            break;
                        case Instructions.Swap:
                            {
                                string var2 = stack.Pop();
                                string var1 = stack.Pop();
                                stack.Push(var2);
                                stack.Push(var1);
                            }
                            break;
                        case Instructions.PushField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push("this." + clsObj.Variables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.StringLen:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.Length", refObj));
                            }
                            break;
                        case Instructions.StringLenBytes:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.ByteCount", refObj));
                            }
                            break;
                        case Instructions.AssignDelegate:
                            {
                                int type = int.Parse(stack.Pop());
                                string val = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} = ({2}){3};\r\n", pre, refObj, fnct[type].Name, val);
                                stack.Push(val);
                            }
                            break;
                        case Instructions.NewObj:
                            {
                                int num = int.Parse(stack.Pop());
                                stack.Push(string.Format("new {0}()", this.structs[num].Name));
                            }
                            break;
                        case Instructions.Delete:
                            {
                                string obj = stack.Pop();
                                res += pre + obj + "= null;\r\n";
                            }
                            break;
                        case Instructions.Clone:
                            {
                                stack.Push(string.Format("call {0}.Clone()", ProcessCondition(stack.Pop())));
                            }
                            break;
                        case Instructions.Dup:
                            {
                                string obj = stack.Pop();
                                stack.Push(obj);
                                stack.Push(obj);
                            }
                            break;
                        case Instructions.SPInc:
                            {
                                res += pre + stack.Pop() + ".spinc();\r\n";
                            }
                            break;
                        case Instructions.SPDec:
                            {
                                res += pre + stack.Pop() + ".spdec();\r\n";
                            }
                            break;
                        case Instructions.StructCreateLocal:
                            {
                                res += pre + string.Format("{0} = new {1}();\r\n", func.LocalVariables[i.Operand1].Name, this.structs[i.Operand2].Name);
                            }
                            break;
                        case Instructions.StructDelLocal:
                            {
                                res += pre + string.Format("{0} = null;\r\n", func.LocalVariables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.STOI:
                            {
                                stack.Push(string.Format("call int.Parse({0})", ProcessCondition(stack.Pop())));
                            }
                            break;
                        case Instructions.ArrayPushBack:
                            {
                                string val=ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.PushBack({2});\r\n", pre, refObj, val);
                            }
                            break;
                        case Instructions.ArrayPopBack:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.PopBack();\r\n", pre, refObj);
                            }
                            break;
                        case Instructions.StringEmpty:
                            {
                                stack.Push(string.Format("call {0}.IsEmpty", ProcessCondition(stack.Pop())));
                            }
                            break;
                        case Instructions.ArrayEmpty:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.IsEmpty", refObj));
                            }
                            break;
                        case Instructions.ArrayRemove:
                            {
                                string index = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.RemoveAt({1})", refObj, index));
                            }
                            break;
                        case Instructions.IncLocal:
                            {
                                res += pre + string.Format("{0}++;\r\n", func.LocalVariables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.DecLocal:
                            {
                                res += pre + string.Format("{0}--;\r\n", func.LocalVariables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.AssignLocal:
                            {
                                res += pre + string.Format("{0} = {1};\r\n", func.LocalVariables[i.Operand1].Name, i.Operand2);
                            }
                            break;
                        case Instructions.StringIndexOf:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());
                                stack.Push(string.Format("call {0}.IndexOf({1})", obj1, obj2));
                            }
                            break;
                        case Instructions.StringSubString:
                            {
                                string count = ProcessCondition(stack.Pop());
                                string index = ProcessCondition(stack.Pop());
                                string obj = ProcessCondition(stack.Pop());
                                stack.Push(string.Format("call {0}.Substring({1},{2})", obj, index, count));
                            }
                            break;
                        case Instructions.SortA:
                            {
                                int funcID = int.Parse(stack.Pop());
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.Sort({2});\r\n", pre, refObj, this.func[funcID].Name);
                            }
                            break;
                        case Instructions.ITOB:
                            {
                                stack.Push("(" + ProcessCondition(stack.Count > 0 ? stack.Pop() : func.LocalVariables[func.LocalVariables.Count - 1].Name) + " == 1)");
                            }
                            break;
                        case Instructions.StringPushBack:
                            {
                                string val = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.PushBack({2});\r\n", pre, refObj, val);
                            }
                            break;
                        case Instructions.StringPopBack:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.PopBack();\r\n", pre, refObj);
                            }
                            break;
                        case Instructions.StringFormat:
                            {
                                string type = stack.Pop();
                                string val = ProcessCondition(stack.Pop());
                                string format = ProcessCondition(stack.Pop());
                                switch (type)
                                {
                                    case "2"://int
                                    case "3"://float
                                    case "4":
                                    case "48":
                                        stack.Push(format + ", " + val);
                                        break;
                                    default:
                                        break;
                                }
                            }
                            break;
                        case Instructions.AddS:
                            {
                                string val = ProcessCondition(stack.Pop());
                                string ori = ProcessCondition(stack.Pop());
                                res += (string.Format("{0}{1} += {2};\r\n", pre, ori, val));
                                stack.Push(string.Format("{0} + {1}", ori, val));
                            }
                            break;
                        case Instructions.ObjSwap:
                            {
                                stack.Pop();
                                string obj2 = GetRef(func, stack);
                                string obj1 = GetRef(func, stack);
                                res += string.Format("{0}tmp = {1};\r\n{0}{1} = {2};\r\n{0}{2} = tmp;\r\n", pre, obj1, obj2);
                            }
                            break;
                        case Instructions.StructRef:
                            {
                            }
                            break;
                        case Instructions.StringPushBackRef:
                            {
                                string val = ProcessCondition(stack.Pop());
                                string obj = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1}.PushBack({2});\r\n", pre, obj, val);
                            }
                            break;
                        case Instructions.StringPopBackRef:
                            {
                                res += string.Format("{0}{1}.PopBack();\r\n", pre, ProcessCondition(stack.Pop()));
                            }
                            break;
                        case Instructions.ITOUI:
                            {
                                string obj = ProcessCondition(stack.Pop());
                                stack.Push(string.Format("((uint){0})", obj));
                            }
                            break;
                        case Instructions.AddUI:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());

                                res += string.Format("{0}{1} += {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.MinUI:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());

                                res += string.Format("{0}{1} -= {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.MulUI:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());

                                res += string.Format("{0}{1} *= {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.DivUI:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());

                                res += string.Format("{0}{1} /= {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.ModUI:
                            {
                                string obj2 = ProcessCondition(stack.Pop());
                                string obj1 = ProcessCondition(stack.Pop());

                                res += string.Format("{0}{1} %= {2};\r\n", pre, obj1, obj2);
                                stack.Push(obj1);
                            }
                            break;
                        case Instructions.AssignUI:
                            {
                                string val = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} = {2};\r\n", pre, refObj, val);
                                stack.Push(refObj);
                            }
                            break;
                        case Instructions.ArrayFind:
                            {
                                int funcID = int.Parse(stack.Pop());
                                string cmpObj = ProcessCondition(stack.Pop());
                                string end = ProcessCondition(stack.Pop());
                                string start = ProcessCondition(stack.Pop());
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.Find({1},{2},{3},{4})", refObj, start, end, cmpObj, this.func[funcID].Name));
                            }
                            break;
                        case Instructions.ArrayReverse:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1}.Reverse();\r\n", pre, refObj);
                            }
                            break;
                        case Instructions.AssignRef:
                            {
                                string refObj = GetRef(func, stack);
                                res += string.Format("{0}{1} = {2};\r\n", pre, ProcessCondition(stack.Pop()), refObj);
                            }
                            break;
                        case Instructions.AssignFieldLocal:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("this.{0} = {1};\r\n", clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.ArraySizeField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push("this." + clsObj.Variables[i.Operand1].Name + ".Length");
                            }
                            break;
                        case Instructions.ArraySizeGlobal:
                            {
                                stack.Push("Global." + this.global[i.Operand1].Name + ".Length");
                            }
                            break;
                        case Instructions.AssignField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("this.{0} = {1};\r\n", clsObj.Variables[i.Operand1].Name, i.Operand2);
                            }
                            break;
                        case Instructions.PushLocal2:
                            {
                                stack.Push(func.LocalVariables[i.Operand1].Name);
                                stack.Push(func.LocalVariables[i.Operand1 + 1].Name);
                            }
                            break;
                        case Instructions.MinLocal:
                            {
                                res += string.Format("{0}{1} -= {2};\r\n", pre, func.LocalVariables[i.Operand1].Name, i.Operand2);
                            }
                            break;
                        case Instructions.BltLocal:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                res += pre + string.Format("if({0} >= {1})\r\n", func.LocalVariables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BgeLocal:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                res += pre + string.Format("if({0} < {1})\r\n", func.LocalVariables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.AssignArrayLocalField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                string obj = func.LocalVariables[i.Operand1].Name;
                                string index = func.LocalVariables[i.Operand1 + 1].Name;
                                string val = "this." + clsObj.Variables[i.Operand2];
                                index = index != "<void>" ? "[" + index + "]" : "";
                                res += string.Format("{0}{1}{2} = {3};\r\n", pre, obj, index, val);
                            }
                            break;
                        case Instructions.AssignGlobalLocal:
                            {
                                res += string.Format("{0}Global.{1} = {2};\r\n", pre, this.global[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.GeField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push(string.Format("({0} > {1})", clsObj.Variables[i.Operand1].Name, i.Operand2));
                            }
                            break;
                        case Instructions.AssignFieldLocalITOB:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += string.Format("{0}this.{1} = {2} == 1;\r\n", pre, clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.AssignLocalField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += string.Format("{0}{1} = this.{2};\r\n", pre, func.LocalVariables[i.Operand1].Name, clsObj.Variables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.BneFieldLocal:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("if(this.{0} == {1})\r\n", clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BgtField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("if(this.{0} <= {1})\r\n", clsObj.Variables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BrFalseField:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("if(this.{0})\r\n", clsObj.Variables[i.Operand1].Name);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BNotEmptyField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("if(this.{0}.IsEmpty)\r\n", clsObj.Variables[i.Operand1].Name);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BneLocal:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                res += pre + string.Format("if({0} == {1})\r\n", func.LocalVariables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BeqField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("if(this.{0} != {1})\r\n", clsObj.Variables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.AssignGlobal:
                            {
                                res += string.Format("{0}Global.{1} = {2};\r\n", pre, this.global[i.Operand1].Name, i.Operand2);
                            }
                            break;
                        case Instructions.ArrayPushBackFieldLocal:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += string.Format("{0}this.{1}.PushBack({2});\r\n", pre, clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.ArrayPushBackGlobalLocal:
                            {
                                res += string.Format("{0}Global.{1}.PushBack({2});\r\n", pre, this.global[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.ArrayPushBackLocal:
                            {
                                res += string.Format("{0}{1}.PushBack({2});\r\n", pre, func.LocalVariables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.BneS:
                            {
                                string refObj = GetRef(func, stack);
                                res += pre + string.Format("if({0} == \"{1}\")\r\n", refObj, this.strings[i.Operand1].Replace("\n", "\\n"));
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.AssignSRef:
                            {
                                string refObj = GetRef(func, stack);
                                string obj = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1} = {2};\r\n", pre, obj, refObj);
                            }
                            break;
                        case Instructions.StringEmptyRef:
                            {
                                string refObj = GetRef(func, stack);
                                stack.Push(string.Format("call {0}.IsEmpty", refObj));                               
                            }
                            break;
                        case Instructions.EqlSFieldLocal:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push(string.Format("(this.{0} == {1})", clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name));
                            }
                            break;
                        case Instructions.EqlSLocal:
                            {
                                stack.Push(string.Format("({0} == \"{1}\")", func.LocalVariables[i.Operand1].Name, this.strings[i.Operand2].Replace("\n", "\\n")));
                            }
                            break;
                        case Instructions.NeqSFieldLocal:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push(string.Format("(this.{0} != {1})", clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name));                            
                            }
                            break;
                        case Instructions.NeqSLocal:
                            {
                                stack.Push(string.Format("({0} != \"{1}\")", func.LocalVariables[i.Operand1].Name, this.strings[i.Operand2].Replace("\n", "\\n")));
                            }
                            break;
                        case Instructions.PushStructRefField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push(string.Format("this.{0}.Clone()", clsObj.Variables[i.Operand1].Name));
                            }
                            break;
                        case Instructions.PushSField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push("this." + clsObj.Variables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.BgtLocal:
                            {
                                if (i.BranchTarget[0] > endIndex)
                                {
                                }
                                res += pre + string.Format("if({0} <= {1})\r\n", func.LocalVariables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.BneField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += pre + string.Format("if(this.{0} == {1})\r\n", clsObj.Variables[i.Operand1].Name, i.Operand2);
                                res += pre + "{\r\n";
                                pre += "    ";
                                branch++;
                            }
                            break;
                        case Instructions.PushSGlobal:
                            {
                                stack.Push("Global." + this.global[i.Operand1].Name);
                            }
                            break;
                        case Instructions.PushSLocal:
                            {
                                stack.Push(func.LocalVariables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.AssignSConst:
                            {
                                string target = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1} = \"{2}\";\r\n", pre, target, this.strings[i.Operand1].Replace("\n", "\\n"));
                            }
                            break;
                        case Instructions.AssignSLocal:
                            {
                                string target = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1} = \"{2}\";\r\n", pre, target, func.LocalVariables[i.Operand1].Name);
                            }
                            break;
                        case Instructions.AssignSFieldLocal:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += (string.Format("{0}this.{1} = {2};\r\n)", pre, clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name));
                            }
                            break;
                        case Instructions.AssignSLocalLocal:
                            {
                                res += string.Format("{0}{1} = {2};\r\n",pre, func.LocalVariables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.ArrayPushBackLocalString:
                            {
                                res += string.Format("{0}{1}.PushBack({2});\r\n", pre, func.LocalVariables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.AssignRefCallStack:
                            {
                                string level = ProcessCondition(stack.Pop());
                                string obj = ProcessCondition(stack.Pop());
                                res += string.Format("{0}{1} = System.GetFuncStackName({2});\r\n", pre, obj, level);
                            }
                            break;
                        case Instructions.StringEmptyLocal:
                            {
                                stack.Push(string.Format("call {0}.IsEmpty", func.LocalVariables[i.Operand1].Name));
                            }
                            break;
                        case Instructions.ArrayPushBackGlobalLocalRef:
                            {
                                res += string.Format("{0}this.{1}.PushBack({2});\r\n", pre, this.global[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.ArrayPushBackFieldLocalRef:
                            {
                                Struct clsObj = GetFuncClass(func);
                                res += string.Format("{0}this.{1}.PushBack({2});\r\n", pre, clsObj.Variables[i.Operand1].Name, func.LocalVariables[i.Operand2].Name);
                            }
                            break;
                        case Instructions.StringEmptyField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push(string.Format("call this.{0}.IsEmpty", clsObj.Variables[i.Operand1].Name));
                            }
                            break;
                        case Instructions.AssignSField:
                            {
                                Struct clsObj = GetFuncClass(func);
                                string val = ProcessCondition(stack.Pop());
                                res += string.Format("{0}this.{1} = {2};\r\n", pre, clsObj.Variables[i.Operand1].Name, val);
                            }
                            break;
                        case Instructions.NeqFieldS:
                            {
                                Struct clsObj = GetFuncClass(func);
                                stack.Push(string.Format("({0} != \"{1}\")", clsObj.Variables[i.Operand1].Name, this.strings[i.Operand2].Replace("\n", "\\n")));
                            }
                            break;
                        case Instructions.LtOrGeLocal:
                            {
                                stack.Push(string.Format("({0} < {1} || {0} >= {2})", func.LocalVariables[i.Operand1].Name, i.Operand2, i.Operand3));
                            }
                            break;
                        case Instructions.AssertFile:
                        case Instructions.AssertFunc:
                        case Instructions.EndOfFunc:
                            break;
                        default:
                            throw new NotSupportedException();

                    }
                    //   res += pre + i + "\r\n";
                }
            }
            while (branch > 0)
            {
                //pre = pre.Substring(0, pre.Length - 4);
                //res += pre + "}\r\n";
                branch--;
            }
            if (switchStarted)
            {
                res += pre + "break;\r\n";
                pre = pre.Substring(8);
                res += pre + "}\r\n";
            }
            pre = pre.Substring(0, pre.Length - 4);
            if (res.StartsWith(pre + "{"))
            {
                string[] token = res.Split('\n');
                StringBuilder sb = new StringBuilder();
                res = "";
                for (int i = 1; i < token.Length; i++)
                {
                    if (string.IsNullOrEmpty(token[i]))
                        continue;
                    sb.Append(token[i].Substring(4) + "\n");
                }
                res = sb.ToString();
            }
            else
            {
                res += pre + "}\r\n";
            }
            return res;
        }
Esempio n. 2
0
 int FindContinueAddress(int endIndex, CodeBlock block)
 {
     for (int index = block.Instructions.Count - 1; index >= 0; index--)
     {
         Instruction i = block.Instructions[index];
         if (i.BranchTarget.Count > 0 && i.BranchTarget[0] >= endIndex)
             return i.BranchTarget[0];
         if (i.Inst == Instructions.DummyCodeBlock)
         {
             int ret = FindContinueAddress(endIndex, block.CodeBlocks[i.Operand1]);
             if (ret >= endIndex)
                 return ret;
         }
     }
     return -1;
 }
Esempio n. 3
0
        void DecompileFunc(Function func)
        {
            CodeBlock block = new CodeBlock();
            int index = 0;
            Dictionary<Instruction, CodeBlock> blockMapping = new Dictionary<Instruction, CodeBlock>();
            string source = "";
            Stack<string> stack = new Stack<string>();
            do
            {
                CodeBlock sub = new CodeBlock();
                block.CodeBlocks.Add(sub);
                index = AnalyzeCodeBlock(sub, func.Instructions, blockMapping, index, -1);
            } while (index < func.Instructions.Count);
            source = func.ToString() + "\r\n";
            source += "{\r\n";
            string pre = "    ";
            for (int i = func.ArgCount; i < func.LocalVariables.Count; i++)
            {
                if (func.LocalVariables[i].Name.StartsWith("<dummy"))
                {
                    string name = Util.GetTypeName(func.LocalVariables[i].VarType, this, func.LocalVariables[i].StructID, func.LocalVariables[i].Dimension);
                    func.LocalVariables[i].Name = "v" + (name.Contains("[") ? name.Substring(0, name.IndexOf("[")) : name).Replace("ref ", "") + i.ToString();
                }
                source += pre + func.LocalVariables[i].ToString().Replace("ref ", "") + ";\r\n";
            }

            foreach (CodeBlock i in block.CodeBlocks)
            {
                source += DumpCodeBlock(func, stack, i, ref pre);
            }
            source += "}\r\n";
            func.SourceCode = source;
        }
Esempio n. 4
0
        int AnalyzeCodeBlock(CodeBlock block, List<Instruction> insns, Dictionary<Instruction, CodeBlock> blockMapping, int index, int endAddress)
        {
            int i = index;
            int continueAddr = int.MaxValue;
            while (i < insns.Count)
            {
                if (i == endAddress)
                    return i;
                Instruction insn = insns[i];
                if (i == index)
                {
                    if (blockMapping.ContainsKey(insn))
                    {
                        Instruction lastInsn = blockMapping[insn].Instructions[blockMapping[insn].Instructions.Count - 1];
                        CodeBlock cur = blockMapping[insn];
                        while (lastInsn.Inst == Instructions.DummyCodeBlock)
                        {
                            cur = cur.CodeBlocks[lastInsn.Operand1];
                            lastInsn = cur.Instructions[cur.Instructions.Count - 1];
                        }
                        foreach (Instruction j in blockMapping[insn].Instructions)
                            block.Instructions.Add(j);
                        foreach (CodeBlock j in blockMapping[insn].CodeBlocks)
                            block.CodeBlocks.Add(j);
                        return insns.IndexOf(lastInsn) + 1;
                    }
                    blockMapping.Add(insn, block);
                }
                if (insn.IsBranchTarget && i != index)
                {
                    CodeBlock newBlock = new CodeBlock();
                    block.CodeBlocks.Add(newBlock);
                    Instruction dummy = new Instruction();
                    dummy.Inst = Instructions.DummyCodeBlock;
                    dummy.Operand1 = block.CodeBlocks.Count - 1;
                    block.Instructions.Add(dummy);
                    i = AnalyzeCodeBlock(newBlock, insns, blockMapping, i, -1);
                    if (newBlock.Instructions.Count == 1)
                    {
                        if (newBlock.Instructions[0].BranchTarget.Count > 0)
                        {
                        }
                    }
                    continue;
                }
                int elseTarget = insn.BranchTarget.Count > 0 ? insn.BranchTarget[0] : int.MaxValue;
                block.Instructions.Add(insn);
                i++;
                if (insn.StartNewBlock)
                {
                    if (insn.BranchTarget[0] > i)
                    {
                        if (insns[i].EndBlock)
                        {
                        }
                        int tmpI = i;
                        int tmpI2 = i;
                        CodeBlock newBlock = new CodeBlock();
                        CodeBlock newBlock2 = null;
                        Instruction dummy2 = null;
                        block.CodeBlocks.Add(newBlock);
                        Instruction dummy = new Instruction();
                        dummy.Inst = Instructions.DummyCodeBlock;
                        dummy.Operand1 = block.CodeBlocks.Count - 1;
                        block.Instructions.Add(dummy);
                        i = AnalyzeCodeBlock(newBlock, insns, blockMapping, i, elseTarget);
                        /*Instruction lastInsn = newBlock.Instructions[newBlock.Instructions.Count - 1];
                        if (lastInsn.Inst == Instructions.DummyCodeBlock)
                        {
                            lastInsn = newBlock.CodeBlocks[lastInsn.Operand1].Instructions.Last();
                        }
                        if (lastInsn.BranchTarget.Count > 0)
                        {
                            continueAddr = lastInsn.BranchTarget[0];
                        }*/
                        continueAddr = FindContinueAddress(elseTarget, newBlock);
                        if ((continueAddr != -1) && !insns[continueAddr - 1].EndBlock)
                        {
                            Instruction continueInsn = insns[continueAddr - 1];
                            continueInsn.EndBlock = true;
                            continueInsn.BranchTarget.Add(continueAddr);
                        }
                        if (continueAddr == elseTarget)
                        {
                            dummy.Operand2 = 1;
                        }

                        bool shouldReturn = false;
                        if (elseTarget < continueAddr)
                        {
                            i = elseTarget;
                            if (i != elseTarget)
                            {
                            }
                            newBlock2 = new CodeBlock();
                            block.CodeBlocks.Add(newBlock2);
                            dummy2 = new Instruction();
                            dummy2.Inst = Instructions.DummyCodeBlock;
                            dummy2.Operand1 = block.CodeBlocks.Count - 1;
                            block.Instructions.Add(dummy2);
                            i = AnalyzeCodeBlock(newBlock2, insns, blockMapping, i, continueAddr);
                            //tmpI2 = i;
                            if (i == continueAddr)
                                shouldReturn = true;
                        }
                        else
                        {
                            shouldReturn = true;
                        }
                        /*i = tmpI;
                        newBlock = new CodeBlock();
                        block.CodeBlocks.Add(newBlock);
                        dummy = new Instruction();
                        dummy.Inst = Instructions.DummyCodeBlock;
                        dummy.Operand1 = block.CodeBlocks.Count - 1;
                        block.Instructions.Add(dummy);
                        i = AnalyzeCodeBlock(newBlock, insns, blockMapping, i);

                        if (newBlock2 != null)
                        {
                            block.CodeBlocks.Add(newBlock2);
                            dummy2.Operand1 = block.CodeBlocks.Count - 1;
                            block.Instructions.Add(dummy2);
                            i = tmpI2;
                        }*/
                        if ((shouldReturn && endAddress == -1) || i >= endAddress)
                            return i;
                        else
                            continue;
                    }
                }

                if ((insn.EndBlock && (((insn.BranchTarget.Count == 0) || insn.BranchTarget[0] > endAddress) || endAddress == -1) && (insn.Inst != Instructions.Ret || (i < insns.Count && insns[i].IsBranchTarget))) || (i >= endAddress && endAddress >= 0))
                {
                    if (i > 1 && (insns[i - 2].Inst == Instructions.Switch || insns[i - 2].Inst == Instructions.SwitchS))
                        endAddress = insns[i - 1].BranchTarget[0];
                    else
                        return i;
                }
            }
            return i;
        }