/// <summary> /// Writes a shortcut for 'type', 'fgs'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'type'.</param> /// <param name="type">The type for which shortcuts should be written.</param> /// <param name="fgs"></param> /// <param name="FAI"></param> public static void WriteFunctionShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI) { int nbTabs = 1; FuncArgInfo[] tailFAI = getTail(FAI); string shortcutCall = getShortcutCall(S, fgs, tailFAI); SB.AppendLine(""); // output comment new Comment("shortcut to " + shortcutCall).Write(SB, S, nbTabs); bool inline = false; bool staticFunc = false; string returnType = FT.GetMangledName(S, fgs.ReturnTypeName); FuncArgInfo returnArgument = null; SB.Append('\t', nbTabs); Functions.WriteDeclaration(SB, S, cgd, inline, staticFunc, returnType, fgs.OutputName, returnArgument, tailFAI); SB.AppendLine(" {"); SB.Append('\t', nbTabs + 1); SB.Append("return "); SB.Append(shortcutCall); SB.AppendLine(";"); SB.Append('\t', nbTabs); SB.AppendLine("}"); }
/// <summary> /// Writes a shortcut for 'type', 'fgs'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'type'.</param> /// <param name="type">The type for which shortcuts should be written.</param> /// <param name="fgs"></param> /// <param name="FAI"></param> public static void WriteFunctionShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI) { int nbTabs = 1; FuncArgInfo[] tailFAI = getTail(FAI); string shortcutCall = getShortcutCall(S, fgs, tailFAI); SB.AppendLine(""); // output comment new Comment("shortcut to " + shortcutCall).Write(SB, S, nbTabs); bool inline = false; bool staticFunc = false; string returnType = FT.GetMangledName(S, fgs.ReturnTypeName); FuncArgInfo returnArgument = null; SB.Append('\t', nbTabs); Functions.WriteDeclaration(SB, S, cgd, inline, staticFunc, returnType, fgs.OutputName, returnArgument, tailFAI); SB.AppendLine(" {"); SB.Append('\t', nbTabs+1); SB.Append("return "); SB.Append(shortcutCall); SB.AppendLine(";"); SB.Append('\t', nbTabs); SB.AppendLine("}"); }
/// <summary> /// Constructs an array of func arg info for all arguments of an G25.fgs. /// </summary> /// <param name="S">Used for retrieving the G25.VariableType of 'm_typeName'.</param> /// <param name="F">Function for which you want an array of FuncArgInfo.</param> /// <param name="nbArgs">Default number of arguments. (the user may not specified arguments and then a default is used).</param> /// <param name="FT">Floating point type of arguments.</param> /// <param name="defaultTypeName">When the user does not specify arguments, this is the default type used.</param> /// <param name="computeMultivectorValue">Set to true to expand all multivector values to symbolic RefGA.Multivectors.</param> /// <returns>Array of FuncArgInfo describing the arguments of 'F'.</returns> public static FuncArgInfo[] GetAllFuncArgInfo(G25.Specification S, G25.fgs F, int nbArgs, G25.FloatType FT, string defaultTypeName, bool computeMultivectorValue) { FuncArgInfo[] FAI = new FuncArgInfo[nbArgs]; for (int i = 0; i < nbArgs; i++) { FAI[i] = new FuncArgInfo(S, F, i, FT, defaultTypeName, computeMultivectorValue); } return(FAI); }
/// <summary> /// Writes generic function based on Instructions. /// /// The other WriteFunction() can figure out the return type automatically, so /// it is preferred over this more verbose version. /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">Function specification.</param> /// <param name="inline">When true, the code is inlined.</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">The type to return (String, can also be e.g. <c>"code"</c>.</param> /// <param name="functionName">Name of generated function.</param> /// <param name="returnArgument">For use with the 'C' language, an extra argument can be used to return results.</param> /// <param name="arguments">Arguments of function (any `return argument' used for the C language is automatically generated).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated code (used for decl only).</param> /// <param name="writeDecl">When false, no declaration is written</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List <Instruction> instructions, Comment comment, bool writeDecl) { // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // declaration: if (writeDecl) { if (comment != null) { comment.Write(cgd.m_declSB, S, 0); } bool inlineDecl = false; // never put inline keywords in declaration WriteDeclaration(cgd.m_declSB, S, cgd, inlineDecl, staticFunc, returnType, functionName, returnArgument, arguments); cgd.m_declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) { comment.Write(defSB, S, 0); } WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); // open function defSB.AppendLine(""); defSB.AppendLine("{"); // add extra instruction for reporting usage of SMVs if (S.m_reportUsage) { instructions.Insert(0, ReportUsage.GetReportInstruction(S, F, arguments)); } if (returnArgument != null) { int nbTabs = 1; instructions.Add(new VerbatimCodeInstruction(nbTabs, "return " + returnArgument.Name + ";")); } // write all instructions foreach (Instruction I in instructions) { I.Write(defSB, S, cgd); } // close function defSB.AppendLine("}"); } // end of WriteFunction()
} // end of WriteFunction() public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List <Instruction> instructions, Comment comment) { bool writeDecl = S.OutputCppOrC(); WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment, writeDecl); }
private static FuncArgInfo[] getTail(FuncArgInfo[] FAI) { if (FAI.Length == 0) { return(null); } else { FuncArgInfo[] tailFAI = new FuncArgInfo[FAI.Length - 1]; Array.Copy(FAI, 1, tailFAI, 0, tailFAI.Length); return(tailFAI); } }
protected void writeSmvPassThroughConverter(FloatType FT, string smvTypeName, Comment comment, string funcName, G25.CG.Shared.FuncArgInfo[] FAI) { // verbatim code List <Instruction> instructions = new List <Instruction>(); int nbTabs = 1; instructions.Add(new VerbatimCodeInstruction(nbTabs, "return " + FAI[0].Name + ";")); G25.CG.Shared.CGdata localCGD = new G25.CG.Shared.CGdata(m_cgd, m_declSB, m_defSB, m_inlineDefSB); string returnType = smvTypeName; bool staticFunc = Functions.OutputStaticFunctions(m_specification); FuncArgInfo returnArgument = null; Functions.WriteFunction(m_specification, localCGD, this.m_fgs, m_specification.m_inlineSet, staticFunc, returnType, funcName, returnArgument, FAI, instructions, comment); }
} // end of WriteFunction() /// <summary> /// Writes a function to 'SB' which assigns a certain 'value' to a certain 'dstName'. /// </summary> /// <param name="S">Used for all kinds of stuff.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="inline">Should the function we inline?</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">String which speficies the return type.</param> /// <param name="returnVarName">The name of the variable which should be returned. Should be one of the argument names.</param> /// <param name="functionName">The name of the function which is to be generated.</param> /// <param name="arguments">Array of FuncArg which describes the arguments of the function.</param> /// <param name="dstFT">Floating point type of destination variable.</param> /// <param name="mustCastDst">set to true if coordinates of 'value' must be cast to 'dstFT'.</param> /// <param name="dstSmv">G25.SMV type of destination.</param> /// <param name="dstName">Name of destination.</param> /// <param name="dstPtr">Is the destination a pointer?</param> /// <param name="value">Value to be written to the destination.</param> /// <param name="returnArgument">For use with the 'C' language, an extra argument can be used to return results.</param> public static void WriteAssignmentFunction( Specification S, G25.CG.Shared.CGdata cgd, bool inline, bool staticFunc, string returnType, string returnVarName, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, FloatType dstFT, bool mustCastDst, G25.SMV dstSmv, string dstName, bool dstPtr, RefGA.Multivector value) { // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // write declaration yes/no? bool writeDecl = (!(dstName.Equals(G25.CG.Shared.SmvUtil.THIS) && S.OutputCpp())) && // no declarations for C++ member functions (!S.OutputCSharpOrJava()); // no declarations in C# and Java if (writeDecl) { WriteDeclaration(cgd.m_declSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); cgd.m_declSB.AppendLine(";"); } WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); defSB.AppendLine(""); defSB.AppendLine("{"); int nbTabs = 1; bool declareVariable = false; AssignInstruction AI = new AssignInstruction(nbTabs, dstSmv, dstFT, mustCastDst, value, dstName, dstPtr, declareVariable); AI.Write(defSB, S, cgd); if (returnVarName != null) { defSB.AppendLine("\treturn " + returnVarName + ";"); } else if (returnArgument != null) { defSB.AppendLine("\treturn " + returnArgument.Name + ";"); } defSB.AppendLine("}"); } // end of WriteAssignmentFunction()
private static void WriteOperatorShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI, G25.Operator op) { // C# does not allow return type of ++ or -- to be different from input type if (S.OutputCSharp() && (op.IsIncrement() || op.IsDecrement()) && (fgs.ReturnTypeName != type.GetName())) { return; } string operatorCall = getOperatorCall(S, fgs, FAI); SB.AppendLine(""); int nbTabs = 1; // output comment new Comment("operator for " + operatorCall).Write(SB, S, nbTabs); bool inline = false; bool staticFunc = true; string returnType = FT.GetMangledName(S, fgs.ReturnTypeName); FuncArgInfo returnArgument = null; SB.Append('\t', nbTabs); Functions.WriteDeclaration(SB, S, cgd, inline, staticFunc, returnType, "operator " + op.Symbol, returnArgument, FAI); SB.AppendLine(" {"); SB.Append('\t', nbTabs + 1); SB.Append("return "); SB.Append(operatorCall); SB.AppendLine(";"); SB.Append('\t', nbTabs); SB.AppendLine("}"); }
/// <summary> /// Writes a function declaration to 'SB'. /// The closing comma is NOT included so the function can also be used as the start of a definition. /// </summary> /// <param name="SB">Where declaration goes.</param> /// <param name="S">Used for all kinds of stuff.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="inline">Should the function we inline?</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">String which speficies the return type.</param> /// <param name="functionName">The name of the function which is to be generated.</param> /// <param name="returnArgument">FuncArgInfo which describes the optional return argument.</param> /// <param name="arguments">Array of FuncArgInfo which describes the arguments of the function.</param> public static void WriteDeclaration(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments) { if (S.OutputJava()) SB.Append("public final "); else if (S.OutputCSharp()) SB.Append("public "); if (staticFunc) SB.Append("static "); SB.Append(G25.CG.Shared.Util.GetInlineString(S, inline, " ")); if (returnArgument != null) returnType = returnArgument.MangledTypeName + "*"; // maybe for C write returnType = returnArgument + "*"? SB.Append(returnType); SB.Append(" "); SB.Append(functionName); SB.Append("("); { // write arguments bool appendComma = false; int nbArgs = (arguments == null) ? 0 : arguments.Length; for (int i = -1; i < nbArgs; i++) // start at -1 for return argument { FuncArgInfo A = null; if (i == -1) { A = returnArgument; if (A == null) continue; } else A = arguments[i]; if (appendComma) SB.Append(", "); if (S.OutputJava()) SB.Append("final "); if (A.Constant && S.OutputCppOrC()) SB.Append("const "); SB.Append(A.MangledTypeName); if (S.OutputCSharpOrJava() && A.IsGMV() && A.MvInterface) SB.Append(Main.IF_SUFFIX); if (A.Array && S.OutputCSharpOrJava()) SB.Append("[]"); SB.Append(" "); if (A.Pointer) SB.Append("*"); else if (S.OutputCpp() && (A.IsMVorOM())) // append '&'? SB.Append("&"); SB.Append(A.Name); if (A.Array && S.OutputCppOrC()) SB.Append("[]"); appendComma = true; } } SB.Append(")"); }
private static string getShortcutCall(Specification S, G25.fgs fgs, FuncArgInfo[] tailFAI) { StringBuilder SB = new StringBuilder(); SB.Append(S.m_namespace); SB.Append("."); SB.Append(fgs.OutputName); SB.Append("(this"); foreach (G25.CG.Shared.FuncArgInfo fai in tailFAI) { SB.Append(", "); SB.Append(fai.Name); } SB.Append(")"); return SB.ToString(); }
private static FuncArgInfo[] getTail(FuncArgInfo[] FAI) { if (FAI.Length == 0) return null; else { FuncArgInfo[] tailFAI = new FuncArgInfo[FAI.Length-1]; Array.Copy(FAI, 1, tailFAI, 0, tailFAI.Length); return tailFAI; } }
} // end of WriteSpecializedFunction() /// <summary> /// Writes a function declaration to 'SB'. /// The closing comma is NOT included so the function can also be used as the start of a definition. /// </summary> /// <param name="SB">Where declaration goes.</param> /// <param name="S">Used for all kinds of stuff.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="inline">Should the function we inline?</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">String which speficies the return type.</param> /// <param name="functionName">The name of the function which is to be generated.</param> /// <param name="returnArgument">FuncArgInfo which describes the optional return argument.</param> /// <param name="arguments">Array of FuncArgInfo which describes the arguments of the function.</param> public static void WriteDeclaration(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments) { if (S.OutputJava()) { SB.Append("public final "); } else if (S.OutputCSharp()) { SB.Append("public "); } if (staticFunc) { SB.Append("static "); } SB.Append(G25.CG.Shared.Util.GetInlineString(S, inline, " ")); if (returnArgument != null) { returnType = returnArgument.MangledTypeName + "*"; // maybe for C write returnType = returnArgument + "*"? } SB.Append(returnType); SB.Append(" "); SB.Append(functionName); SB.Append("("); { // write arguments bool appendComma = false; int nbArgs = (arguments == null) ? 0 : arguments.Length; for (int i = -1; i < nbArgs; i++) // start at -1 for return argument { FuncArgInfo A = null; if (i == -1) { A = returnArgument; if (A == null) { continue; } } else { A = arguments[i]; } if (appendComma) { SB.Append(", "); } if (S.OutputJava()) { SB.Append("final "); } if (A.Constant && S.OutputCppOrC()) { SB.Append("const "); } SB.Append(A.MangledTypeName); if (S.OutputCSharpOrJava() && A.IsGMV() && A.MvInterface) { SB.Append(Main.IF_SUFFIX); } if (A.Array && S.OutputCSharpOrJava()) { SB.Append("[]"); } SB.Append(" "); if (A.Pointer) { SB.Append("*"); } else if (S.OutputCpp() && (A.IsMVorOM())) // append '&'? { SB.Append("&"); } SB.Append(A.Name); if (A.Array && S.OutputCppOrC()) { SB.Append("[]"); } appendComma = true; } } SB.Append(")"); } // end of WriteDeclaration()
private static void WriteOperatorShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI, G25.Operator op) { // C# does not allow return type of ++ or -- to be different from input type if (S.OutputCSharp() && (op.IsIncrement() || op.IsDecrement()) && (fgs.ReturnTypeName != type.GetName())) return; string operatorCall = getOperatorCall(S, fgs, FAI); SB.AppendLine(""); int nbTabs = 1; // output comment new Comment("operator for " + operatorCall).Write(SB, S, nbTabs); bool inline = false; bool staticFunc = true; string returnType = FT.GetMangledName(S, fgs.ReturnTypeName); FuncArgInfo returnArgument = null; SB.Append('\t', nbTabs); Functions.WriteDeclaration(SB, S, cgd, inline, staticFunc, returnType, "operator " + op.Symbol, returnArgument, FAI); SB.AppendLine(" {"); SB.Append('\t', nbTabs+1); SB.Append("return "); SB.Append(operatorCall); SB.AppendLine(";"); SB.Append('\t', nbTabs); SB.AppendLine("}"); }
/// <summary> /// Checks if an operator should be written for the combination of 'type' and 'fgs'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'type'.</param> /// <param name="type">The type for which shortcuts should be written.</param> /// <param name="fgs"></param> /// <param name="FAI"></param> /// <param name="operatorMap"></param> /// <param name="boundOperators"></param> private static void WriteOperatorShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI, Dictionary<string, List<G25.Operator>> operatorMap, Dictionary<string, bool> boundOperators) { if (S.OutputJava() || S.OutputC()) return; // cannot override operators in Java or C // check for, get entry in operatorMap for fgs.OutputName if (!operatorMap.ContainsKey(fgs.OutputName)) return; List<G25.Operator> opList = operatorMap[fgs.OutputName]; // check if number of arguments matches foreach (G25.Operator op in opList) { if (op.NbArguments == fgs.NbArguments) { // check if this operator already bound to function with the same arguments string uniqueOpArgId = op.Symbol; for (int a = 0; a < fgs.NbArguments; a++) uniqueOpArgId += "~_~" + fgs.m_argumentTypeNames[a]; if (boundOperators.ContainsKey(uniqueOpArgId)) continue; else boundOperators[uniqueOpArgId] = true; WriteOperatorShortcut(SB, S, cgd, FT, type, fgs, FAI, op); } } }
/// <summary> /// Writes generic function based on Instructions. /// /// The other WriteFunction() can figure out the return type automatically, so /// it is preferred over this more verbose version. /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">Function specification.</param> /// <param name="inline">When true, the code is inlined.</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">The type to return (String, can also be e.g. <c>"code"</c>.</param> /// <param name="functionName">Name of generated function.</param> /// <param name="returnArgument">For use with the 'C' language, an extra argument can be used to return results.</param> /// <param name="arguments">Arguments of function (any `return argument' used for the C language is automatically generated).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated code (used for decl only).</param> /// <param name="writeDecl">When false, no declaration is written</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List<Instruction> instructions, Comment comment, bool writeDecl) { // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // declaration: if (writeDecl) { if (comment != null) comment.Write(cgd.m_declSB, S, 0); bool inlineDecl = false; // never put inline keywords in declaration WriteDeclaration(cgd.m_declSB, S, cgd, inlineDecl, staticFunc, returnType, functionName, returnArgument, arguments); cgd.m_declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) comment.Write(defSB, S, 0); WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); // open function defSB.AppendLine(""); defSB.AppendLine("{"); // add extra instruction for reporting usage of SMVs if (S.m_reportUsage) instructions.Insert(0, ReportUsage.GetReportInstruction(S, F, arguments)); if (returnArgument != null) { int nbTabs = 1; instructions.Add(new VerbatimCodeInstruction(nbTabs, "return " + returnArgument.Name + ";")); } // write all instructions foreach (Instruction I in instructions) { I.Write(defSB, S, cgd); } // close function defSB.AppendLine("}"); }
/// <summary> /// /// </summary> /// <param name="S">Used for all kinds of stuff.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="inline">Should the function we inline?</param> /// <param name="staticFunc">Static function?</param> /// <param name="functionName">The name of the function which is to be generated.</param> /// <param name="arguments">Array of FuncArg which describes the arguments of the function.</param> /// <param name="returnFT">Floating point type of return variable.</param> /// <param name="mustCastDst">set to true if coordinates of 'value' must be cast to 'dstFT'.</param> /// <param name="returnType">The type to be returned.</param> /// <param name="value">Value to be written to the returned.</param> public static void WriteReturnFunction( Specification S, G25.CG.Shared.CGdata cgd, bool inline, bool staticFunc, string functionName, FuncArgInfo[] arguments, FloatType returnFT, bool mustCastDst, G25.VariableType returnType, RefGA.Multivector value) { string returnTypeName; bool returnSMV = returnType is G25.SMV; if (returnSMV) returnTypeName = returnFT.GetMangledName(S, (returnType as G25.SMV).Name); else returnTypeName = (returnType as G25.FloatType).type; // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // declaration: if (S.OutputCppOrC()) { WriteDeclaration(cgd.m_declSB, S, cgd, false, staticFunc, returnTypeName, functionName, null, arguments); cgd.m_declSB.AppendLine(";"); } WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnTypeName, functionName, null, arguments); defSB.AppendLine(""); defSB.AppendLine("{"); int nbTabs = 1; ReturnInstruction RI = new ReturnInstruction(nbTabs, returnType, returnFT, mustCastDst, value); RI.Write(defSB, S, cgd); defSB.Append("\n"); defSB.AppendLine("}"); }
/// <summary> /// Writes generic function based on Instructions. /// /// This version automatically figures out the return type (so it is recommended over the other WriteFunction()). /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">Function specification.</param> /// <param name="inline">When true, the code is inlined.</param> /// <param name="staticFunc">static function?</param> /// <param name="functionName">Name of generated function.</param> /// <param name="arguments">Arguments of function (any 'return argument' used for the C language is automatically setup correctly).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated declration code.</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string functionName, FuncArgInfo[] arguments, List<Instruction> instructions, Comment comment) { List<G25.VariableType> returnTypes = new List<G25.VariableType>(); List<G25.FloatType> returnTypeFT = new List<G25.FloatType>(); // floating point types of return types Instruction.GetReturnType(instructions, returnTypes, returnTypeFT); // for now, assume only one return type is used? string returnType = "void"; G25.CG.Shared.FuncArgInfo returnArgument = null; if (returnTypes.Count > 0) { G25.VariableType returnVT = returnTypes[0]; G25.FloatType returnFT = returnTypeFT[0]; if (returnVT is G25.FloatType) returnVT = returnFT; string returnTypeName = (returnVT is G25.MV) ? (returnVT as G25.MV).Name : (returnVT as FloatType).type; returnType = returnFT.GetMangledName(S, returnTypeName); if (S.OutputC()) { if (!(returnVT is G25.FloatType)) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, returnFT, returnTypeName, false); // false = compute value } } } WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment); }
public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List<Instruction> instructions, Comment comment) { bool writeDecl = S.OutputCppOrC(); WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment, writeDecl); }
private static string getOperatorCall(Specification S, G25.fgs fgs, FuncArgInfo[] FAI) { StringBuilder SB = new StringBuilder(); SB.Append(S.m_namespace); SB.Append("."); SB.Append(fgs.OutputName); SB.Append("("); bool comma = false; foreach (G25.CG.Shared.FuncArgInfo fai in FAI) { if (comma) SB.Append(", "); comma = true; SB.Append(fai.Name); } SB.Append(")"); return SB.ToString(); }
/// <summary> /// Writes a function to 'SB' which assigns a certain 'value' to a certain 'dstName'. /// </summary> /// <param name="S">Used for all kinds of stuff.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="inline">Should the function we inline?</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">String which speficies the return type.</param> /// <param name="returnVarName">The name of the variable which should be returned. Should be one of the argument names.</param> /// <param name="functionName">The name of the function which is to be generated.</param> /// <param name="arguments">Array of FuncArg which describes the arguments of the function.</param> /// <param name="dstFT">Floating point type of destination variable.</param> /// <param name="mustCastDst">set to true if coordinates of 'value' must be cast to 'dstFT'.</param> /// <param name="dstSmv">G25.SMV type of destination.</param> /// <param name="dstName">Name of destination.</param> /// <param name="dstPtr">Is the destination a pointer?</param> /// <param name="value">Value to be written to the destination.</param> /// <param name="returnArgument">For use with the 'C' language, an extra argument can be used to return results.</param> public static void WriteAssignmentFunction( Specification S, G25.CG.Shared.CGdata cgd, bool inline, bool staticFunc, string returnType, string returnVarName, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, FloatType dstFT, bool mustCastDst, G25.SMV dstSmv, string dstName, bool dstPtr, RefGA.Multivector value) { // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // write declaration yes/no? bool writeDecl = (!(dstName.Equals(G25.CG.Shared.SmvUtil.THIS) && S.OutputCpp())) && // no declarations for C++ member functions (!S.OutputCSharpOrJava()); // no declarations in C# and Java if (writeDecl) { WriteDeclaration(cgd.m_declSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); cgd.m_declSB.AppendLine(";"); } WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); defSB.AppendLine(""); defSB.AppendLine("{"); int nbTabs = 1; bool declareVariable = false; AssignInstruction AI = new AssignInstruction(nbTabs, dstSmv, dstFT, mustCastDst, value, dstName, dstPtr, declareVariable); AI.Write(defSB, S, cgd); if (returnVarName != null) { defSB.AppendLine("\treturn " + returnVarName + ";"); } else if (returnArgument != null) { defSB.AppendLine("\treturn " + returnArgument.Name + ";"); } defSB.AppendLine("}"); }
// add someextra instructions for report usage? // add extra verbatim code here if rep usage? // what arguments are required?? public static Instruction GetReportInstruction(Specification S, G25.fgs F, FuncArgInfo[] FAI) { if ((S.OutputC()) || (!S.m_reportUsage) || (FAI.Length == 0)) return new NOPinstruction(); // check if all arguments are GMVs for (int i = 0; i < FAI.Length; i++) { if (!FAI[i].IsGMV()) return new NOPinstruction(); } // get XML spec string XMLstr = GetXMLstring(S, F, FAI); StringBuilder SB = new StringBuilder(); if (S.OutputCSharpOrJava()) { for (int i = 0; i < FAI.Length; i++) { SB.AppendLine("SmvType type_" + FAI[i].Name + " = " + FAI[i].Name + ".to_" + FAI[i].MangledTypeName +"().m_t;"); } } { string MV_CONSTANT = GetSpecializedConstantName(S, S.m_GMV.Name); string INVALID_CONSTANT = GetSpecializedConstantName(S, INVALID); // output the test for all specialized MVs SB.Append("if ("); for (int i = 0; i < FAI.Length; i++) { if (i > 0) { SB.AppendLine(" && "); SB.Append("\t"); } if (S.OutputCpp()) { SB.Append("(" + FAI[i].Name + ".m_t > " + MV_CONSTANT + ") && (" + FAI[i].Name + ".m_t < " + INVALID_CONSTANT + ")"); } else if (S.OutputCSharp()) { SB.Append("(type_" + FAI[i].Name + " > SmvType." + MV_CONSTANT + ") && (type_" + FAI[i].Name + " < SmvType." + INVALID_CONSTANT + ")"); } else if (S.OutputJava()) { SB.Append("(type_" + FAI[i].Name + ".compareTo(SmvType." + MV_CONSTANT + ") > 0) && (type_" + FAI[i].Name + ".compareTo(SmvType." + INVALID_CONSTANT + ") < 0)"); } } SB.AppendLine(") {"); if (S.OutputCpp()) { SB.Append("\t\tstd::string reportUsageString = std::string(\"\") + "); } else if (S.OutputCSharp()) { SB.Append("\t\tstring reportUsageString = "); } else if (S.OutputJava()) { SB.Append("\t\tString reportUsageString = "); } // output XMLstr, replace placeholders with code int XMLstrIdx = 0; int argIdx = 0; while (XMLstrIdx < XMLstr.Length) { string placeHolder = GetPlaceHolderString(argIdx); int nextIdx = XMLstr.IndexOf(placeHolder, XMLstrIdx); if (nextIdx < 0) nextIdx = XMLstr.Length; SB.Append(Util.StringToCode(XMLstr.Substring(XMLstrIdx, nextIdx - XMLstrIdx))); if (argIdx < FAI.Length) { if (S.OutputCpp()) { SB.Append("+ g_" + S.m_namespace + "Typenames[" + FAI[argIdx].Name + ".m_t] + "); } else if (S.OutputCSharp()) { SB.Append("+ typenames[(int)type_" + FAI[argIdx].Name + "] + "); } else if (S.OutputJava()) { SB.Append("+ typenames[type_" + FAI[argIdx].Name + ".getId()] + "); } } argIdx++; XMLstrIdx = nextIdx + placeHolder.Length; } SB.AppendLine(";"); if (S.OutputCpp()) { SB.AppendLine("\t\tReportUsage::mergeReport(new ReportUsage(reportUsageString));"); } else if (S.OutputCSharp()) { SB.AppendLine("\t\tReportUsage.MergeReport(new ReportUsage(reportUsageString));"); } else if (S.OutputJava()) { SB.AppendLine("\t\tReportUsage.mergeReport(new ReportUsage(reportUsageString));"); } SB.AppendLine("}"); } int nbTabs = 1; return new VerbatimCodeInstruction(nbTabs, SB.ToString()); }
private static string GetXMLstring(Specification S, G25.fgs F, FuncArgInfo[] FAI) { // no return forced type in XML string returnTypeName = null; // get placeholder arguments for XML string[] argumentTypeNames = new string[FAI.Length]; for (int i = 0; i < FAI.Length; i++) { argumentTypeNames[i] = GetPlaceHolderString(i); } // use a single float type only in XML string[] floatNames = new string[1] { FAI[0].FloatType.type }; // get a copy of F, but put insert placeholders for the typenames G25.fgs tmpF = new G25.fgs(F.Name, F.OutputName, returnTypeName, argumentTypeNames, F.ArgumentVariableNames, floatNames, F.MetricName, F.Comment, F.Options); string XMLstr = XML.FunctionToXmlString(S, tmpF); return XMLstr; }
/// <summary> /// Constructs an array of func arg info for all arguments of an G25.fgs. /// </summary> /// <param name="S">Used for retrieving the G25.VariableType of 'm_typeName'.</param> /// <param name="F">Function for which you want an array of FuncArgInfo.</param> /// <param name="nbArgs">Default number of arguments. (the user may not specified arguments and then a default is used).</param> /// <param name="FT">Floating point type of arguments.</param> /// <param name="defaultTypeName">When the user does not specify arguments, this is the default type used.</param> /// <param name="computeMultivectorValue">Set to true to expand all multivector values to symbolic RefGA.Multivectors.</param> /// <returns>Array of FuncArgInfo describing the arguments of 'F'.</returns> public static FuncArgInfo[] GetAllFuncArgInfo(G25.Specification S, G25.fgs F, int nbArgs, G25.FloatType FT, string defaultTypeName, bool computeMultivectorValue) { FuncArgInfo[] FAI = new FuncArgInfo[nbArgs]; for (int i = 0; i < nbArgs; i++) { FAI[i] = new FuncArgInfo(S, F, i, FT, defaultTypeName, computeMultivectorValue); } return FAI; }