} // end of WriteFunctions() /// <summary> /// Writes a simple function which assigns some value based on specialized multivectors or scalars to some variable. /// /// Used by a lot of simple C functions, like gp, op, lc. /// /// Somewhat obsolete (preferably, use the more generic, instruction based 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">The function generation specification.</param> /// <param name="FT">Default float pointer type.</param> /// <param name="FAI">Info on the arguments of the function.</param> /// <param name="value">The value to assign.</param> /// <param name="comment">Optional comment for function (can be null).</param> public static void WriteSpecializedFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, RefGA.Multivector value, Comment comment) { // get return type (may be a G25.SMV or a G25.FloatType) G25.VariableType returnType = G25.CG.Shared.SpecializedReturnType.GetReturnType(S, cgd, F, FT, value); if (returnType == null) { throw new G25.UserException("Missing return type: " + G25.CG.Shared.BasisBlade.MultivectorToTypeDescription(S, value), XML.FunctionToXmlString(S, F)); } bool ptr = true; string dstName = G25.fgs.RETURN_ARG_NAME; //string dstTypeName = (returnType is G25.SMV) ? FT.GetMangledName((returnType as G25.SMV).Name) : (returnType as G25.FloatType).type; string funcName = F.OutputName; // write comment to declaration if (comment != null) { if (S.OutputCppOrC()) { comment.Write(cgd.m_declSB, S, 0); } else { comment.Write(cgd.m_defSB, S, 0); } } if ((returnType is G25.SMV) && (S.OutputC())) { bool mustCast = false; G25.SMV dstSmv = returnType as G25.SMV; G25.CG.Shared.FuncArgInfo returnArgument = null; returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, dstSmv.Name, false); // false = compute value bool staticFunc = S.OutputCSharpOrJava(); G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineFunctions, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, dstSmv, dstName, ptr, value); } else { G25.FloatType returnFT = ((returnType as G25.FloatType) == null) ? FT : (returnType as G25.FloatType); bool mustCast = false; for (int i = 0; i < FAI.Length; i++) { mustCast |= returnFT.MustCastIfAssigned(S, FAI[i].FloatType); } bool staticFunc = S.OutputCSharpOrJava(); G25.CG.Shared.Functions.WriteReturnFunction(S, cgd, S.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnType, value); } } // end of WriteSpecializedFunction()
/// <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()
private static void WriteExplicitConverterCSharp(StringBuilder SB, Specification S, FloatType FT, G25.fgs fgs, SMV srcSmv, SMV dstSmv) { string srcTypeName = FT.GetMangledName(S, srcSmv.GetName()); string dstTypeName = FT.GetMangledName(S, dstSmv.GetName()); string argName = "x"; string extraComment = null; Comment comment = GetComment(S, srcTypeName, dstTypeName, argName, extraComment); comment.Write(SB, S, 1); SB.AppendLine("\tpublic static explicit operator " + dstTypeName + " (" + srcTypeName + " " + argName + ") {"); SB.AppendLine("\t\treturn " + S.m_namespace + "." + FT.GetMangledName(S, fgs.m_outputName) + /*dstTypeName*/ "(" + argName + ");"); SB.AppendLine("\t}"); }
private static void WriteConvertingConstructor(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.fgs fgs, SMV srcSmv, SMV dstSmv) { string srcTypeName = FT.GetMangledName(S, srcSmv.GetName()); string dstTypeName = FT.GetMangledName(S, dstSmv.GetName()); string argName = "x"; Comment comment = new Comment("Converting constructor, from " + srcTypeName + " to " + dstTypeName); comment.Write(SB, S, 1); SB.AppendLine("\tpublic " + dstTypeName + "(" + srcTypeName + " " + argName + ") {"); int nbTabs = 2; bool declareVariable = false; bool cast = false; bool srcPtr = false; bool dstPtr = false; RefGA.Multivector value = Symbolic.SMVtoSymbolicMultivector(S, srcSmv, argName, srcPtr); AssignInstruction AI = new AssignInstruction(nbTabs, dstSmv, FT, cast, value, SmvUtil.THIS, dstPtr, declareVariable); AI.Write(SB, S, cgd); SB.AppendLine("\t}"); }
public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; string srcTypeName = FT.GetMangledName(S, srcOm.Name); string dstTypeName = FT.GetMangledName(S, dstOm.Name); bool writeDecl = S.OutputC(); string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : ""; string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : ""); string CONST = (S.OutputCppOrC()) ? "const " : ""; string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)"; // write comment, function declaration Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" + "Warning 1: coordinates which cannot be represented are silenty lost.\n" + "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n"); if (writeDecl) { comment.Write(declSB, S, 0); declSB.Append(funcDecl); declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) comment.Write(defSB, S, 0); defSB.Append(funcDecl); { defSB.AppendLine(" {"); Dictionary<Tuple<int, int, int>, Tuple<int, int, double>> D = dstOm.getMapping(srcOm); StringBuilder copySB = new StringBuilder(); List<string> setToZero = new List<string>(); string matrixStr = (S.OutputC()) ? "m" : "m_m"; string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr; string ptrStr = (S.OutputC()) ? "->" : "."; // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null // Do not use foreach() on D because we want to fill in coordinates in their proper order. for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++) { for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++) { for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++) { Tuple<int, int, int> key = new Tuple<int, int, int>(gradeIdx, somDomainIdx, somRangeIdx); int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx); string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = "; if (D.ContainsKey(key)) { Tuple<int, int, double> value = D[key]; int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2); double multiplier = value.Value3; string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * "); copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];"); } else { setToZero.Add(dstString); } } } } // append copy statements defSB.Append(copySB); // append statements to set coordinates to zero if (setToZero.Count > 0) { int cnt = 0; defSB.Append("\t"); foreach (string str in setToZero) { defSB.Append(str); cnt++; if (cnt > 8) { cnt = 0; defSB.AppendLine(""); defSB.Append("\t\t"); } } defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";"); } defSB.AppendLine("}"); } }
} // end of WriteSetVectorImages() public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; string srcTypeName = FT.GetMangledName(S, srcOm.Name); string dstTypeName = FT.GetMangledName(S, dstOm.Name); bool writeDecl = S.OutputC(); string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : ""; string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : ""); string CONST = (S.OutputCppOrC()) ? "const " : ""; string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)"; // write comment, function declaration Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" + "Warning 1: coordinates which cannot be represented are silenty lost.\n" + "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n"); if (writeDecl) { comment.Write(declSB, S, 0); declSB.Append(funcDecl); declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) { comment.Write(defSB, S, 0); } defSB.Append(funcDecl); { defSB.AppendLine(" {"); Dictionary <Tuple <int, int, int>, Tuple <int, int, double> > D = dstOm.getMapping(srcOm); StringBuilder copySB = new StringBuilder(); List <string> setToZero = new List <string>(); string matrixStr = (S.OutputC()) ? "m" : "m_m"; string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr; string ptrStr = (S.OutputC()) ? "->" : "."; // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null // Do not use foreach() on D because we want to fill in coordinates in their proper order. for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++) { for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++) { for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++) { Tuple <int, int, int> key = new Tuple <int, int, int>(gradeIdx, somDomainIdx, somRangeIdx); int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx); string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = "; if (D.ContainsKey(key)) { Tuple <int, int, double> value = D[key]; int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2); double multiplier = value.Value3; string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * "); copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];"); } else { setToZero.Add(dstString); } } } } // append copy statements defSB.Append(copySB); // append statements to set coordinates to zero if (setToZero.Count > 0) { int cnt = 0; defSB.Append("\t"); foreach (string str in setToZero) { defSB.Append(str); cnt++; if (cnt > 8) { cnt = 0; defSB.AppendLine(""); defSB.Append("\t\t"); } } defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";"); } defSB.AppendLine("}"); } }
/// <summary> /// Writes a simple function which assigns some value based on specialized multivectors or scalars to some variable. /// /// Used by a lot of simple C functions, like gp, op, lc. /// /// Somewhat obsolete (preferably, use the more generic, instruction based 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">The function generation specification.</param> /// <param name="FT">Default float pointer type.</param> /// <param name="FAI">Info on the arguments of the function.</param> /// <param name="value">The value to assign.</param> /// <param name="comment">Optional comment for function (can be null).</param> public static void WriteSpecializedFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, RefGA.Multivector value, Comment comment) { // get return type (may be a G25.SMV or a G25.FloatType) G25.VariableType returnType = G25.CG.Shared.SpecializedReturnType.GetReturnType(S, cgd, F, FT, value); if (returnType == null) throw new G25.UserException("Missing return type: " + G25.CG.Shared.BasisBlade.MultivectorToTypeDescription(S, value), XML.FunctionToXmlString(S, F)); bool ptr = true; string dstName = G25.fgs.RETURN_ARG_NAME; //string dstTypeName = (returnType is G25.SMV) ? FT.GetMangledName((returnType as G25.SMV).Name) : (returnType as G25.FloatType).type; string funcName = F.OutputName; // write comment to declaration if (comment != null) { if (S.OutputCppOrC()) comment.Write(cgd.m_declSB, S, 0); else comment.Write(cgd.m_defSB, S, 0); } if ((returnType is G25.SMV) && (S.OutputC())) { bool mustCast = false; G25.SMV dstSmv = returnType as G25.SMV; G25.CG.Shared.FuncArgInfo returnArgument = null; returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, dstSmv.Name, false); // false = compute value bool staticFunc = S.OutputCSharpOrJava(); G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineFunctions, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, dstSmv, dstName, ptr, value); } else { G25.FloatType returnFT = ((returnType as G25.FloatType) == null) ? FT : (returnType as G25.FloatType); bool mustCast = false; for (int i = 0; i < FAI.Length; i++) mustCast |= returnFT.MustCastIfAssigned(S, FAI[i].FloatType); bool staticFunc = S.OutputCSharpOrJava(); G25.CG.Shared.Functions.WriteReturnFunction(S, cgd, S.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnType, value); } }
/// <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> /// Writes code for all converters (as specified in Function Generation Specification). /// </summary> public void WriteConverter() { try { string rawSrcTypeName = m_fgs.GetArgumentTypeName(0, null); // null = no default name string rawDstTypeName = m_fgs.Name.Substring(1); // dest = function name minus the underscore. bool srcIsGMV = m_specification.m_GMV.GetName().Equals(rawSrcTypeName); const int nbArgs = 1; foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string srcTypeName = FT.GetMangledName(m_specification, rawSrcTypeName); string dstTypeName = FT.GetMangledName(m_specification, rawDstTypeName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, nbArgs, FT, m_specification.m_GMV.Name, computeMultivectorValue); // comment: Comment comment = GetComment(m_specification, srcTypeName, dstTypeName, FAI[0].Name, m_fgs.Comment); comment.Write((m_specification.OutputCSharpOrJava()) ? m_defSB : m_declSB, m_specification, 1); string funcName = G25.CG.Shared.Converter.GetConverterName(m_specification, m_fgs, srcTypeName, dstTypeName); if (srcIsGMV) { // convert GMV to SMV writeGmvToSmvConverter(FT, srcTypeName, dstTypeName, comment, funcName, FAI); } else if (srcTypeName == dstTypeName) { // convert to the same type writeSmvPassThroughConverter(FT, srcTypeName, comment, funcName, FAI); } else { // convert SMV/scalar to SMV // if scalar or specialized: generate specialized function: first get symbolic result RefGA.Multivector value = FAI[0].MultivectorValue[0]; G25.CG.Shared.CGdata localCGD = new G25.CG.Shared.CGdata(m_cgd, m_declSB, m_defSB, m_inlineDefSB); G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(m_specification, m_fgs, -1, FT, rawDstTypeName, false); // false = compute value bool staticFunc = Functions.OutputStaticFunctions(m_specification); bool mustCast = false; if (m_specification.OutputC()) { Functions.WriteAssignmentFunction(m_specification, localCGD, m_specification.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, returnArgument.Type as G25.SMV, returnArgument.Name, returnArgument.Pointer, value); } else { Functions.WriteReturnFunction( m_specification, localCGD, m_specification.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnArgument.Type as G25.SMV, value); } } } } catch (G25.UserException E) { if (E.m_XMLerrorSource.Length == 0) { string XMLstring = XML.FunctionToXmlString(m_specification, m_fgs); m_cgd.AddError(new G25.UserException(E.m_message, XMLstring, E.m_filename, E.m_line, E.m_column)); } else { m_cgd.AddError(E); } } } // end of function WriteConverter()