public Statement (Parser yyp, FunctionCall fc ):base(((LSLSyntax )yyp)){ kids . Add ( fc ); }
public FunctionCallExpression (Parser yyp, FunctionCall fc ):base(((LSLSyntax )yyp)){ kids . Add ( fc ); }
/// <summary> /// Generates the code for a FunctionCall node. /// </summary> /// <param name="fc">The FunctionCall node.</param> /// <returns>String containing C# code for FunctionCall fc.</returns> private string GenerateFunctionCall(FunctionCall fc) { string retstr = ""; bool marc = FuncCallsMarc(); string Mname = ""; bool isEnumerable = false; string tempString = ""; string FunctionCalls = ""; int NeedCloseParent = 0; foreach (SYMBOL kid in fc.kids) { // if (kid is ArgumentList && m_SLCompatabilityMode) if (kid is ArgumentList) { ArgumentList al = kid as ArgumentList; int comma = al.kids.Count - 1; // tells us whether to print a comma foreach (SYMBOL s in al.kids) { if (s is BinaryExpression) { BinaryExpression be = s as BinaryExpression; //FunctionCalls += GenerateNode(s); if (be.ExpressionSymbol.Equals("&&") || be.ExpressionSymbol.Equals("||")) { // special case handling for logical and/or, see Mantis 3174 tempString += "((bool)("; tempString += GenerateNode((SYMBOL)be.kids.Pop()); tempString += "))"; tempString += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0, 1)), be); tempString += "((bool)("; foreach (SYMBOL kidb in be.kids) retstr += GenerateNode(kidb); tempString += "))"; } else { tempString += GenerateNode((SYMBOL)be.kids.Pop()); tempString += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); foreach (SYMBOL kidb in be.kids) { if (kidb is FunctionCallExpression) { tempString += GenerateNode(kidb); } else if (kidb is TypecastExpression) { tempString += Generate(String.Format("({0}) (", ((TypecastExpression)kidb).TypecastType)); tempString += GenerateNode((SYMBOL)kidb.kids.Pop()); tempString += Generate(")"); } else tempString += GenerateNode(kidb); } } } else if (s is TypecastExpression) { tempString += Generate(String.Format("({0}) (", ((TypecastExpression)s).TypecastType)); tempString += GenerateNode((SYMBOL)s.kids.Pop()); tempString += Generate(")"); } else { tempString += GenerateNode(s); } if (0 < comma--) tempString += Generate(", "); } } else { tempString += GenerateNode(kid); } } /* string TempStringForEnum = ""; TempStringForEnum = OriginalScript.Remove(0, fc.pos); TempStringForEnum = TempStringForEnum.Remove(0, fc.Id.Length); TempStringForEnum = TempStringForEnum.Split(')')[0]; string TestOriginal = OriginalScript.Replace(" ", ""); TestOriginal = TestOriginal.Replace("\n", ""); string TestScript = fc.Id + TempStringForEnum + ")" + "{"; string TestTestScript = fc.Id + "(*){"; foreach (string testOriginal in TestOriginal.Split(';')) { if (testOriginal.CompareWildcard(TestTestScript, true)) { isEnumerable = true; } } if (TestOriginal.Contains(TestScript)) { //This DOES need to exist, this is for nested function calls to user-generated methods! isEnumerable = true; } else if (retstr.ToString().Contains("IEnumerator " + fc.Id)) { isEnumerable = true; } */ isEnumerable = false; bool DTFunction = false; string rettype = "void"; if (LocalMethods.TryGetValue(fc.Id, out rettype)) isEnumerable = true; else if (DTFunctions.Contains(fc.Id)) { DTFunction = true; } if (DTFunction) { // retstr.Append(GenerateLine("{")); retstr += Generate("yield return "); retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); retstr += tempString; retstr += GenerateLine(")"); // retstr.Append(Generate("yield return null;")); // retstr.Append(GenerateLine("}")); } else if (isEnumerable) { if (rettype != "void") { Mname = RandomString(10, true); FunctionCalls += GenerateLine(rettype + " " + Mname + ";"); } FunctionCalls += GenerateLine("{"); //We can use enumerator here as the { in the above line breaks off possible issues upward in the method (or should anyway) FunctionCalls += Generate("IEnumerator enumerator = "); FunctionCalls += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); FunctionCalls += tempString; FunctionCalls += Generate(");"); FunctionCalls += GenerateLine("while (true)"); FunctionCalls += GenerateLine("{"); string FunctionName = RandomString(10, true); FunctionCalls += GenerateLine("bool " + FunctionName + " = false;"); FunctionCalls += GenerateLine("try"); FunctionCalls += GenerateLine("{"); FunctionCalls += GenerateLine("" + FunctionName + " = enumerator.MoveNext();"); FunctionCalls += GenerateLine("if(!" + FunctionName + ")"); FunctionCalls += GenerateLine("break;"); //All done, break out of the loop FunctionCalls += GenerateLine("}"); FunctionCalls += GenerateLine("catch"); FunctionCalls += GenerateLine("{"); FunctionCalls += GenerateLine("yield break;");//End it since we are erroring out -> now abort FunctionCalls += GenerateLine("}"); //End of catch FunctionCalls += GenerateLine("if( enumerator.Current == null || enumerator.Current is DateTime) yield return enumerator.Current;"); //Let the other things process for a bit here at the end of each enumeration FunctionCalls += GenerateLine("else break;"); //Let the other things process for a bit here at the end of each enumeration FunctionCalls += GenerateLine("}"); //End of while if (rettype != "void") { FunctionCalls += GenerateLine(Mname + " = (" + rettype + ") enumerator.Current;"); retstr += Mname; } FunctionCalls += GenerateLine("}"); FuncCalls.Add(FunctionCalls); } else { retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); retstr += tempString; retstr += Generate(")"); } /* if (FunctionCalls != "") { retstr.Append(Generate(";")); //We do this because we can't just do ) } .... otherwise we have issues! // Add it to the end so that everything is covered //so that lines like 'if(test) callStatement(FunctionCall());' //don't error out because of brackets retstr.Append(GenerateLine("}")); retstr.Append(GenerateLine("TESTREMOVE")); //Gets removed later and tells it not to print a ; at the end } */ //Function calls are first return DumpFunc(marc) + retstr.ToString(); }
/// <summary> /// Generates the code for a FunctionCall node. /// </summary> /// <param name="fc">The FunctionCall node.</param> /// <returns>String containing C# code for FunctionCall fc.</returns> private string GenerateFunctionCall(FunctionCall fc, bool NeedRetVal) { string retstr = ""; bool marc = FuncCallsMarc(); string Mname = ""; bool isEnumerable = false; string tempString = ""; //int NeedCloseParent = 0; foreach (SYMBOL kid in fc.kids) { // if (kid is ArgumentList && m_SLCompatabilityMode) if (kid is ArgumentList) { ArgumentList al = kid as ArgumentList; int comma = al.kids.Count - 1; // tells us whether to print a comma foreach (SYMBOL s in al.kids) { if (s is BinaryExpression) { BinaryExpression be = s as BinaryExpression; //FunctionCalls += GenerateNode(s); if (be.ExpressionSymbol.Equals("&&") || be.ExpressionSymbol.Equals("||")) { // special case handling for logical and/or, see Mantis 3174 tempString += "((bool)("; tempString += GenerateNode((SYMBOL)be.kids.Pop()); tempString += "))"; tempString += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0, 1)), be); tempString += "((bool)("; foreach (SYMBOL kidb in be.kids) retstr += GenerateNode(kidb); tempString += "))"; } else { tempString += GenerateNode((SYMBOL)be.kids.Pop()); tempString += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); foreach (SYMBOL kidb in be.kids) { if (kidb is FunctionCallExpression) { tempString += GenerateNode(kidb); } else if (kidb is TypecastExpression) { tempString += Generate(String.Format("({0}) (", ((TypecastExpression)kidb).TypecastType)); tempString += GenerateNode((SYMBOL)kidb.kids.Pop()); tempString += Generate(")"); } else tempString += GenerateNode(kidb); } } } else if (s is TypecastExpression) { tempString += Generate(String.Format("({0}) (", ((TypecastExpression)s).TypecastType)); tempString += GenerateNode((SYMBOL)s.kids.Pop()); tempString += Generate(")"); } else { tempString += GenerateNode(s); } if (0 < comma--) tempString += Generate(", "); } } else { tempString += GenerateNode(kid); } } isEnumerable = false; bool DTFunction = false; string rettype = "void"; if (LocalMethods.TryGetValue(fc.Id, out rettype)) isEnumerable = true; /* suspended.. API fails with IEnums else if (IenFunctions.TryGetValue(fc.Id, out rettype)) isEnumerable = true; */ else if (DTFunctions.Contains(fc.Id)) { DTFunction = true; } //Check whether this function is an API function if (m_apiFunctions.ContainsKey(CheckName(fc.Id))) { //Add the m_apis link fc.Id = String.Format("(({0})m_apis[\"{1}\"]).{2}", m_apiFunctions[CheckName(fc.Id)].InterfaceName, m_apiFunctions[CheckName(fc.Id)].Name, fc.Id); } if (DTFunction) { retstr += Generate("yield return "); retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); retstr += tempString; retstr += Generate(")"); } else if (isEnumerable) { if (m_isInEnumeratedDeclaration && NeedRetVal) //Got to have a retVal for do/while { //This is for things like the do/while statement, where a function is in the while() part and can't be dumped in front of the do/while string MethodName = RandomString(10, true); string typeDefs = ""; ObjectList arguements = null; if (LocalMethodArguements.TryGetValue(fc.Id, out arguements)) { // print the state arguments, if any foreach (SYMBOL kid in arguements) { if (kid is ArgumentDeclarationList) { ArgumentDeclarationList ADL = (ArgumentDeclarationList)kid; typeDefs += (GenerateArgumentDeclarationList(ADL)) + ","; } } } if (typeDefs.Length != 0) typeDefs = typeDefs.Remove(typeDefs.Length - 1); string newMethod = string.Format("private {0} {1}({2}, out bool ahwowuerogng)", rettype, MethodName, typeDefs); newMethod += (Generate("{")); newMethod += (Generate("ahwowuerogng = true;")); Mname = RandomString(10, true); newMethod += (Generate("IEnumerator " + Mname + " = ")); newMethod += (Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); newMethod += (tempString); newMethod += (Generate(");")); newMethod += (Generate(" try {")); newMethod += (Generate(Mname + ".MoveNext();")); newMethod += (Generate(" if(" + Mname + ".Current != null)")); newMethod += (Generate(" return (" + rettype + ")" + Mname + ".Current;")); newMethod += (Generate(" }")); //End of try newMethod += (Generate(" catch(Exception ex) ")); newMethod += (Generate(" {")); newMethod += (Generate(" }")); //End of catch newMethod += (Generate("ahwowuerogng = true;")); newMethod += (Generate("return default(" + rettype + ");")); //End while newMethod += "}"; MethodsToAdd.Add(newMethod); List<string> fCalls = new List<string>(); string boolname = RandomString(10, true); fCalls.Add(Generate("bool " + boolname + " = true;")); retstr += MethodName + "(" + tempString + ", out " + boolname + ")"; lock (FuncCalls) FuncCalls.AddRange(fCalls); } else { //Function calls are added to the DumpFunc command, and will be dumped safely before the statement that occurs here, so we don't have to deal with the issues behind having { and } in this area. Mname = RandomString(10, true); string Exname = RandomString(10, true); List<string> fCalls = new List<string>(); fCalls.Add(Generate("string " + Exname + " = \"\";")); fCalls.Add(Generate("IEnumerator " + Mname + " = ")); fCalls.Add(Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); fCalls.Add(tempString); fCalls.Add(Generate(");")); fCalls.Add(Generate("while (true) {")); fCalls.Add(Generate(" try {")); fCalls.Add(Generate(" if(!" + Mname + ".MoveNext())")); fCalls.Add(Generate(" break;")); fCalls.Add(Generate(" }")); //End of try fCalls.Add(Generate(" catch(Exception ex) ")); fCalls.Add(Generate(" {")); fCalls.Add(Generate(" " + Exname + " = ex.Message;")); fCalls.Add(Generate(" }")); //End of catch fCalls.Add(Generate(" if(" + Exname + " != \"\")")); fCalls.Add(Generate(" yield return " + Exname + ";")); //Exceptions go first fCalls.Add(Generate(" else if(" + Mname + ".Current == null || " + Mname + ".Current is DateTime)")); fCalls.Add(Generate(" yield return " + Mname + ".Current;")); //Let the other things process for a bit here at the end of each enumeration fCalls.Add(Generate(" else break;")); //Let the other things process for a bit here at the end of each enumeration fCalls.Add(Generate(" }")); //End while if (NeedRetVal && rettype != "void") { retstr += " (" + rettype + ") " + Mname + ".Current"; } lock (FuncCalls) FuncCalls.AddRange(fCalls); } } else { retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); retstr += tempString; retstr += Generate(")"); } //Function calls are first if needed return DumpFunc(marc) + retstr.ToString(); }
/// <summary> /// Generates the code for a FunctionCall node. /// </summary> /// <param name="fc">The FunctionCall node.</param> /// <returns>String containing C# code for FunctionCall fc.</returns> private string GenerateFunctionCall(FunctionCall fc, bool NeedRetVal) { string retstr = String.Empty; //Check whether this function is an API function if (m_apiFunctions.ContainsKey(CheckName(fc.Id))) { //Add the m_apis link fc.Id = String.Format("(({0})m_apis[\"{1}\"]).{2}", m_apiFunctions[CheckName(fc.Id)].InterfaceName, m_apiFunctions[CheckName(fc.Id)].Name, fc.Id); } retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); foreach (SYMBOL kid in fc.kids) retstr += GenerateNode(kid); retstr += Generate(")"); return retstr; }
/// <summary> /// Generates the code for a FunctionCall node. /// </summary> /// <param name="fc">The FunctionCall node.</param> /// <returns>String containing C# code for FunctionCall fc.</returns> private string GenerateFunctionCall(FunctionCall fc) { StringBuilder retstr = new StringBuilder(); string tempString = ""; foreach (SYMBOL kid in fc.kids) tempString += GenerateNode(kid); //We can assume pretty well that there are no enumerator functions in the legacy parser, as only state events are IEnumerator, and you can't call those //We still MUST check these though! bool DTFunction = false; if (DTFunctions.Contains(fc.Id)) DTFunction = true; if (DTFunction && IsParentEnumerable) { retstr.Append(GenerateLine("{")); retstr.Append(Generate("yield return ")); retstr.Append(Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); retstr.Append(tempString); retstr.Append(GenerateLine(");")); retstr.Append(Generate("yield return null")); retstr.Append(GenerateLine("}")); } else if (DTFunction) { //Uhoh, sleeping in a void.... it returns a DT, // but we can't handle like in the other enumerator places // so we have to force the sleep in HERE retstr.Append(GenerateLine("{")); retstr.Append("DateTime time = " + Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); retstr.Append(tempString); retstr.Append(GenerateLine(");")); //Ex. --- //DateTime time = DateTime.Now.AddMilliseconds(10000); // 10 s //System.Threading.Thread.Sleep((DateTime.Now - time).TotalMilliseconds); //End Ex. --- //Do the sleep now retstr.Append("System.Threading.Thread.Sleep((DateTime.Now - time).TotalMilliseconds);"); retstr.Append(GenerateLine("}")); } return retstr.ToString(); }
/// <summary> /// Generates the code for a FunctionCall node. /// </summary> /// <param name="fc">The FunctionCall node.</param> /// <returns>String containing C# code for FunctionCall fc.</returns> private string GenerateFunctionCall(FunctionCall fc) { StringBuilder retstr = new StringBuilder(); bool isEnumerable = false; string tempString = ""; string FunctionCalls = ""; foreach (SYMBOL kid in fc.kids) { if (kid is ArgumentList && m_SLCompatabilityMode) { ArgumentList al = kid as ArgumentList; int comma = al.kids.Count - 1; // tells us whether to print a comma foreach (SYMBOL s in al.kids) { if (s is BinaryExpression) { BinaryExpression be = s as BinaryExpression; //FunctionCalls += GenerateNode(s); if (be.ExpressionSymbol.Equals("&&") || be.ExpressionSymbol.Equals("||")) { // special case handling for logical and/or, see Mantis 3174 tempString += "((bool)("; tempString += GenerateNode((SYMBOL)be.kids.Pop()); tempString += "))"; tempString += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0, 1)), be); tempString += "((bool)("; foreach (SYMBOL kidb in be.kids) retstr.Append(GenerateNode(kidb)); tempString += "))"; } else { tempString += GenerateNode((SYMBOL)be.kids.Pop()); tempString += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); foreach (SYMBOL kidb in be.kids) { if (kidb is FunctionCallExpression) { string FunctionName = RandomString(10, true); if (FunctionCalls == "") { FunctionCalls += GenerateLine("{"); //Add extra bracketing } FunctionCalls += "object "+FunctionName+" = " + GenerateNode(kidb) + ";"; tempString += FunctionName; } else tempString += GenerateNode(kidb); } } } else { tempString += GenerateNode(s); } if (0 < comma--) tempString += Generate(", "); } } else { tempString += GenerateNode(kid); } } string TempStringForEnum = ""; TempStringForEnum = OriginalScript.Remove(0, fc.pos); TempStringForEnum = TempStringForEnum.Remove(0, fc.Id.Length); TempStringForEnum = TempStringForEnum.Split(')')[0]; string TestOriginal = OriginalScript.Replace(" ", ""); TestOriginal = TestOriginal.Replace("\n", ""); string TestScript = fc.Id + TempStringForEnum + ")" + "{"; string TestTestScript = fc.Id + "(*){"; foreach (string testOriginal in TestOriginal.Split(';')) { if (testOriginal.CompareWildcard(TestTestScript, true)) { isEnumerable = true; } } if (TestOriginal.Contains(TestScript)) { //This DOES need to exist, this is for nested function calls to user-generated methods! isEnumerable = true; } else if (retstr.ToString().Contains("IEnumerator " + fc.Id)) { isEnumerable = true; } bool DTFunction = false; if (DTFunctions.Contains(fc.Id)) { DTFunction = true; } if (DTFunction) { retstr.Append(GenerateLine("{")); retstr.Append(Generate("yield return ")); retstr.Append(Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); retstr.Append(tempString); retstr.Append(GenerateLine(");")); retstr.Append(Generate("yield return null;")); retstr.Append(GenerateLine("}")); } else if (isEnumerable) { retstr.Append(GenerateLine("{")); retstr.Append(Generate("IEnumerator enumerator = ")); retstr.Append(Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); retstr.Append(tempString); retstr.Append(Generate(");")); retstr.Append(GenerateLine("while (true)")); retstr.Append(GenerateLine("{")); retstr.Append(GenerateLine("bool running = false;")); retstr.Append(GenerateLine("try")); retstr.Append(GenerateLine("{")); retstr.Append(GenerateLine("running = enumerator.MoveNext();")); retstr.Append(GenerateLine("if(!running)")); retstr.Append(GenerateLine("break;")); //All done, break out of the loop retstr.Append(GenerateLine("}")); retstr.Append(GenerateLine("catch")); retstr.Append(GenerateLine("{")); retstr.Append(GenerateLine("break;"));//End it since we are erroring out retstr.Append(GenerateLine("}")); //End of catch retstr.Append(GenerateLine("yield return enumerator.Current;")); //Let the other things process for a bit here at the end of each enumeration retstr.Append(GenerateLine("}")); //End of while retstr.Append(GenerateLine("}")); retstr.Append(GenerateLine("TESTREMOVE")); //Gets removed later and tells it not to print a ; at the end } else { retstr.Append(Generate(String.Format("{0}(", CheckName(fc.Id)), fc)); retstr.Append(tempString); retstr.Append(Generate(")")); } if (FunctionCalls != "") { retstr.Append(Generate(";")); //We do this because we can't just do ) } .... otherwise we have issues! // Add it to the end so that everything is covered //so that lines like 'if(test) callStatement(FunctionCall());' //don't error out because of brackets retstr.Append(GenerateLine("}")); retstr.Append(GenerateLine("TESTREMOVE")); //Gets removed later and tells it not to print a ; at the end } //Function calls are first return FunctionCalls + retstr; }