public Statement(Parser yyp, FunctionCall fc) : base((yyp)) { kids.Add(fc); }
/// <summary> /// Generates the code for a FunctionCall node. /// </summary> /// <param name="fc">The FunctionCall node.</param> /// <param name="NeedRetVal"></param> /// <returns>String containing C# code for FunctionCall fc.</returns> string GenerateFunctionCall(FunctionCall fc, bool NeedRetVal) { StringBuilder retVal = new StringBuilder(), tmpVal = new StringBuilder(); bool marc = FuncCallsMarc(); string Mname = ""; bool isEnumerable = false; //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 tmpVal.Append("((bool)("); tmpVal.Append(GenerateNode((SYMBOL) be.kids.Pop())); tmpVal.Append("))"); tmpVal.Append(Generate(string.Format(" {0} ", be.ExpressionSymbol.Substring(0, 1)), be)); tmpVal.Append("((bool)("); foreach (SYMBOL kidb in be.kids) retVal.Append(GenerateNode(kidb)); tmpVal.Append("))"); } else { tmpVal.Append(GenerateNode((SYMBOL) be.kids.Pop())); tmpVal.Append(Generate(string.Format(" {0} ", be.ExpressionSymbol), be)); foreach (SYMBOL kidb in be.kids) { if (kidb is FunctionCallExpression) { tmpVal.Append(GenerateNode(kidb)); } else if (kidb is TypecastExpression) { tmpVal.Append(Generate(string.Format("({0}) (", ((TypecastExpression) kidb).TypecastType))); tmpVal.Append(GenerateNode((SYMBOL) kidb.kids.Pop())); tmpVal.Append(Generate(")")); } else tmpVal.Append(GenerateNode(kidb)); } } } else if (s is TypecastExpression) { tmpVal.Append(Generate(string.Format("({0}) (", ((TypecastExpression) s).TypecastType))); tmpVal.Append(GenerateNode((SYMBOL) s.kids.Pop())); tmpVal.Append(Generate(")")); } else { tmpVal.Append(GenerateNode(s)); } if (0 < comma--) tmpVal.Append(Generate(", ")); } } else { tmpVal.Append(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("((dynamic)m_apis[\"{0}\"]).{1}", m_apiFunctions[CheckName(fc.Id)].Name, fc.Id); } if (DTFunction) { retVal.Append(Generate("yield return ")); retVal.Append(Generate(string.Format("{0}(", CheckName(fc.Id)), fc)); retVal.Append(tmpVal.ToString()); retVal.Append(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 = StringUtils.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 = StringUtils.RandomString(10, true); newMethod += (Generate("System.Collections.IEnumerator " + Mname + " = ")); newMethod += (Generate(string.Format("{0}(", CheckName(fc.Id)), fc)); newMethod += (tmpVal.ToString()); 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 = StringUtils.RandomString(10, true); fCalls.Add(Generate("bool " + boolname + " = true;")); retVal.Append(MethodName + "(" + tmpVal + ", 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 = StringUtils.RandomString(10, true); string Exname = StringUtils.RandomString(10, true); List<string> fCalls = new List<string> { Generate("string " + Exname + " = \"\";"), Generate("System.Collections.IEnumerator " + Mname + " = "), Generate(string.Format("{0}(", CheckName(fc.Id)), fc), tmpVal.ToString(), Generate(");"), Generate("while (true) {"), Generate(" try {"), Generate(" if(!" + Mname + ".MoveNext())"), Generate(" break;"), Generate(" }"), Generate(" catch(Exception ex) "), Generate(" {"), Generate(" " + Exname + " = ex.Message;"), Generate(" }"), Generate(" if(" + Exname + " != \"\")"), Generate(" yield return " + Exname + ";"), Generate(" else if(" + Mname + ".Current == null || " + Mname + ".Current is DateTime)"), Generate(" yield return " + Mname + ".Current;"), Generate(" else break;"), Generate(" }") }; //Let the other things process for a bit here at the end of each enumeration //Let the other things process for a bit here at the end of each enumeration if (NeedRetVal && rettype != "void") { retVal.Append(" (" + rettype + ") " + Mname + ".Current"); } lock (FuncCalls) FuncCalls.AddRange(fCalls); } } else { retVal.Append(Generate(string.Format("{0}(", CheckName(fc.Id)), fc)); retVal.Append(tmpVal.ToString()); retVal.Append(Generate(")")); } //Function calls are first if needed return DumpFunc(marc) + retVal + DumpAfterFunc(marc); }
public FunctionCallExpression(Parser yyp, FunctionCall fc) : base((yyp)) { kids.Add(fc); }