private static void WriteDefinition(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Constant C) { // assume only SMV constants for now G25.SMV smv = C.Type as G25.SMV; ConstantSMV Csmv = C as ConstantSMV; string className = FT.GetMangledName(S, smv.Name); // MANGLED_TYPENAME MANGLED_CONSTANT_NAME = {...} SB.Append(className); SB.Append(" "); SB.Append(FT.GetMangledName(S, C.Name)); if (smv.NbNonConstBasisBlade > 0) { // MANGLED_TYPENAME MANGLED_CONSTANT_NAME(...) SB.Append("(" + className + "::" + G25.CG.Shared.SmvUtil.GetCoordinateOrderConstant(S, smv)); for (int c = 0; c < smv.NbNonConstBasisBlade; c++) { SB.Append(", "); SB.Append(FT.DoubleToString(S, Csmv.Value[c])); } SB.Append(")"); } SB.AppendLine(";"); }
/// <summary> /// Writes constructors of a SOM class to 'SB'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'SOM'.</param> /// <param name="som">The specialized outermorphism for which the class should be written.</param> /// <param name="rangeVectorSMVname">The name of the SMV which can represent a column of the OM.</param> public static void WriteConstructors(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som, string rangeVectorSMVname) { string className = FT.GetMangledName(S, som.Name); string gomClassName = (S.m_GOM == null) ? "" : FT.GetMangledName(S, S.m_GOM.Name); cgd.m_cog.EmitTemplate(SB, "SOMconstructors", "S=", S, "FT=", FT, "som=", som, "className=", className, "gomClassName=", gomClassName, "rangeVectorSMVname=", rangeVectorSMVname); }
private static void WriteDefinition(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Constant C) { // assume only SMV constants for now G25.SMV smv = C.Type as G25.SMV; ConstantSMV Csmv = C as ConstantSMV; // MANGLED_TYPENAME MANGLED_CONSTANT_NAME = {...} SB.Append(FT.GetMangledName(S, C.Type.GetName())); SB.Append(" "); SB.Append(FT.GetMangledName(S, C.Name)); SB.Append(" = {"); if (smv.NbNonConstBasisBlade == 0) { // 'C' does not allow empty structs, so there is a filler that must be initialized SB.Append("0"); } else { if (S.m_coordStorage == COORD_STORAGE.ARRAY) SB.Append("{"); for (int c = 0; c < smv.NbNonConstBasisBlade; c++) { if (c > 0) SB.Append(", "); SB.Append(FT.DoubleToString(S, Csmv.Value[c])); } if (S.m_coordStorage == COORD_STORAGE.ARRAY) SB.Append("}"); } SB.AppendLine("};"); }
/// <summary> /// Writes the definition of an GOM struct to 'SB' (including comments). /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'GOM'.</param> /// <param name="gom">The general outermorphism for which the struct should be written.</param> public static void WriteGOMclass(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GOM gom) { SB.AppendLine(""); string className = FT.GetMangledName(S, gom.Name); // get range vector type G25.SMV rangeVectorType = G25.CG.Shared.OMinit.getRangeVectorType(S, FT, cgd, gom); string rangeVectorSMVname = FT.GetMangledName(S, rangeVectorType.Name); WriteComment(SB, S, cgd, FT, gom); // typedef SB.AppendLine("class " + className); SB.AppendLine("{"); // member vars WriteMemberVariables(SB, S, cgd, FT, gom); SB.AppendLine("public:"); // Float type WriteFloatType(SB, S, cgd, FT, gom, className); // constructors WriteConstructors(SB, S, cgd, FT, gom, className, rangeVectorSMVname); // operator= WriteAssignmentOps(SB, S, cgd, FT, gom, className, rangeVectorSMVname); // set(...) WriteSetDeclarations(SB, S, cgd, FT, gom, className, rangeVectorSMVname); SB.AppendLine("}; // end of " + className); }
/// <summary> /// Generates a source file with the GOM class definition. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <returns></returns> public static string GenerateCode(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT) { G25.GOM gom = S.m_GOM; string className = FT.GetMangledName(S, gom.Name); // get range vector type G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, gom); string rangeVectorSMVname = FT.GetMangledName(S, rangeVectorType.Name); // get filename, list of generated filenames List<string> generatedFiles = new List<string>(); string sourceFilename = MainGenerator.GetClassOutputPath(S, className); generatedFiles.Add(sourceFilename); // get StringBuilder where all generated code goes StringBuilder SB = new StringBuilder(); // get a new 'cgd' where all ouput goes to the one StringBuilder SB cgd = new G25.CG.Shared.CGdata(cgd, SB, SB, SB); // output license, copyright G25.CG.Shared.Util.WriteCopyright(SB, S); G25.CG.Shared.Util.WriteLicense(SB, S); // open namespace G25.CG.Shared.Util.WriteOpenNamespace(SB, S); // write class comment G25.CG.CSJ.GOM.WriteComment(SB, S, cgd, FT, gom); // open class G25.CG.Shared.Util.WriteOpenClass(SB, S, G25.CG.Shared.AccessModifier.AM_public, className, null, null); // write member variables G25.CG.CSJ.GOM.WriteMemberVariables(SB, S, cgd, FT, gom); // write constructors G25.CG.CSJ.GOM.WriteConstructors(SB, S, cgd, FT, gom, className, rangeVectorSMVname); // write set functions G25.CG.CSJ.GOM.WriteSetIdentity(SB, S, cgd, FT); G25.CG.CSJ.GOM.WriteSetCopy(SB, S, cgd, FT); G25.CG.CSJ.GOM.WriteSetVectorImages(S, cgd, FT, false, false); // false, false = matrixMode, transpose G25.CG.CSJ.GOM.WriteSetVectorImages(S, cgd, FT, true, false); // true, false = matrixMode, transpose G25.CG.CSJ.GOM.WriteSOMtoGOMcopy(S, cgd, FT); // write shortcuts for functions G25.CG.Shared.Shortcut.WriteFunctionShortcuts(SB, S, cgd, FT, gom); // close class G25.CG.Shared.Util.WriteCloseClass(SB, S, className); // close namespace G25.CG.Shared.Util.WriteCloseNamespace(SB, S); // write all to file G25.CG.Shared.Util.WriteFile(sourceFilename, SB.ToString()); return sourceFilename; }
/// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { StringBuilder declSB = m_cgd.m_declSB; bool inline = false; // never inline GMV functions StringBuilder defSB = (inline) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string funcName = FT.GetMangledName(m_specification, m_fgs.OutputName); m_funcName[FT.type] = funcName; // setup hashtable with template arguments: System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["functionName"] = funcName; argTable["FT"] = FT; argTable["mvType"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["randomScalarFuncName"] = m_randomScalarFunc[floatName]; argTable["gpopFuncName"] = m_gpopFunc[floatName]; argTable["normFuncName"] = m_normFunc[floatName]; argTable["gpScalarFuncName"] = m_scalarGpFunc[floatName]; argTable["generatorVersor"] = (IsVersor(m_fgs) ? true : false); if (m_specification.OutputCppOrC()) { // header m_cgd.m_cog.EmitTemplate(declSB, "randomBladeVersorHeader", argTable); } // source m_cgd.m_cog.EmitTemplate(defSB, "randomBladeVersor", argTable); } } // end of WriteFunction
} // end of CheckTestingDepencies() /// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); if (m_trueGmvFunc) // GMV test { testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["randomVersorFuncName"] = m_randomVersorFuncName[FT.type]; argTable["subtractFuncName"] = m_subtractGmvFuncName[FT.type]; argTable["gpFuncName"] = m_gpFuncName[FT.type]; argTable["versorInverseFuncName"] = m_versorInverseFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testIGP_GMV", argTable); } else if ((m_smv1 != null) && (m_smv2 != null) && m_smv1.CanConvertToGmv(m_specification) && m_smv2.CanConvertToGmv(m_specification) && (m_specification.GetType(m_fgs.m_returnTypeName) as G25.MV).CanConvertToGmv(m_specification)) { // SMV test testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["smv1"] = m_smv1; argTable["smv2"] = m_smv2; argTable["smv1Name"] = FT.GetMangledName(m_specification, m_smv1.Name); argTable["smv2Name"] = FT.GetMangledName(m_specification, m_smv2.Name); argTable["smvRName"] = FT.GetMangledName(m_specification, m_fgs.m_returnTypeName); argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["randomSmv1FuncName"] = m_randomSmv1FuncName[FT.type]; argTable["randomSmv2FuncName"] = m_randomSmv2FuncName[FT.type]; argTable["gpFuncName"] = m_gpFuncName[FT.type]; argTable["subtractFuncName"] = m_subtractGmvFuncName[FT.type]; argTable["versorInverseFuncName"] = m_versorInverseFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testIGP_SMV", argTable); } } return(testFuncNames); } // end of WriteTestFunction()
/// <summary> /// Writes constructors. /// </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 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteConstructors(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { cgd.m_cog.EmitTemplate(SB, "SMVconstructors", "S=", S, "smv=", smv, "className=", FT.GetMangledName(S, smv.Name), "gmvClassName=", FT.GetMangledName(S, S.m_GMV.Name), "FT=", FT); }
/// <summary> /// Writes set functions.. /// </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 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteSetDeclarations(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { cgd.m_cog.EmitTemplate(SB, "SMVsetDecl", "S=", S, "smv=", smv, "className=", FT.GetMangledName(S, smv.Name), "gmvClassName=", FT.GetMangledName(S, S.m_GMV.Name), "FT=", FT); }
private static void WriteDeclaration(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Constant C) { // extern MANGLED_TYPENAME MANGLED_CONSTANT_NAME; if (C.Comment.Length > 0) SB.AppendLine("/** " + C.Comment + " */"); SB.Append("extern "); SB.Append(FT.GetMangledName(S, C.Type.GetName())); SB.Append(" "); SB.Append(FT.GetMangledName(S, C.Name)); SB.AppendLine(";"); }
private static void WriteDeclaration(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Constant C) { // extern MANGLED_TYPENAME MANGLED_CONSTANT_NAME; if (C.Comment.Length > 0) { SB.AppendLine("/** " + C.Comment + " */"); } SB.Append("extern "); SB.Append(FT.GetMangledName(S, C.Type.GetName())); SB.Append(" "); SB.Append(FT.GetMangledName(S, C.Name)); SB.AppendLine(";"); }
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}"); }
/// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); if (m_gmvFunc) // GMV test { testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["euclideanBasisVectorBitmap"] = m_G25M.GetEuclideanBasisVectorBitmap(); argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["randomBladeFuncName"] = m_randomBladeFuncName[FT.type]; argTable["opGmvFunc"] = m_opFuncName[FT.type]; argTable["expGmvFunc"] = m_expFuncName[FT.type]; argTable["subtractGmvFuncName"] = m_subtractGmvFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testEuclideanLogGMV", argTable); } else if ((m_smv != null) && m_smv.CanConvertToGmv(m_specification)) // SMV test { testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["rotorType"] = m_smv; argTable["rotorName"] = FT.GetMangledName(m_specification, m_smv.Name); argTable["bivectorName"] = FT.GetMangledName(m_specification, m_fgs.m_returnTypeName); argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["randomBivectorFuncName"] = m_randomBivectorFuncName[FT.type]; argTable["expBivectorFunc"] = m_expBivectorFuncName[FT.type]; argTable["subtractRotorFuncName"] = m_subtractRotorFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testEuclideanLogSMV", argTable); } } return(testFuncNames); } // end of WriteTestFunction()
/// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); if (m_gmvFunc) // GMV test { testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["randomBladeFuncName"] = m_randomBladeFuncName[FT.type]; argTable["reverseFuncName"] = m_reverseFuncName[FT.type]; argTable["spFuncName"] = m_spFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testUnitGMV", argTable); } else if ((m_smv != null) && m_smv.CanConvertToGmv(m_specification)) // SMV test { testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["smv"] = m_smv; argTable["smvName"] = FT.GetMangledName(m_specification, m_smv.Name); argTable["resultSmvName"] = FT.GetMangledName(m_specification, m_fgs.m_returnTypeName); argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["randomSmvFuncName"] = m_randomSmvFuncName[FT.type]; argTable["reverseFuncName"] = m_reverseFuncName[FT.type]; argTable["spFuncName"] = m_spFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testUnitSMV", argTable); } } return(testFuncNames); } // end of WriteTestFunction()
/// <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> /// This function should check the dependencies of this function. If dependencies are /// missing, the function can complain (throw exception) or fix it (add the required functions). /// /// If changes are made to the specification then it must be locked first because /// multiple threads run in parallel which may all modify the specification! /// </summary> public override void CheckDepencies() { string GMVname = m_specification.m_GMV.Name; // check dependencies for all float types foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); m_GMVname[floatName] = FT.GetMangledName(m_specification, GMVname); //bool returnTrueName = false; m_randomScalarFunc[floatName] = G25.CG.Shared.Dependencies.GetDependency(m_specification, m_cgd, RandomScalar.RANDOM + floatName, new string[0], floatName, FT, null); //if (m_specification.m_outputLanguage != OUTPUT_LANGUAGE.C) // m_randomScalarFunc[floatName] = FT.GetMangledName(m_specification, m_randomScalarFunc[floatName]); m_normFunc[floatName] = G25.CG.Shared.Dependencies.GetDependency(m_specification, m_cgd, "norm", new string[] { GMVname }, FT, m_G25M.m_name) + G25.CG.Shared.CANSparts.RETURNS_SCALAR; m_scalarGpFunc[floatName] = G25.CG.Shared.Dependencies.GetDependency(m_specification, m_cgd, "gp", new string[] { GMVname, floatName }, FT, null); // null = no metric for op required if (IsBlade(m_fgs)) { m_gpopFunc[floatName] = G25.CG.Shared.Dependencies.GetDependency(m_specification, m_cgd, "op", new string[] { GMVname, GMVname }, FT, null); // null = no metric for op required } else if (IsVersor(m_fgs)) { m_gpopFunc[floatName] = G25.CG.Shared.Dependencies.GetDependency(m_specification, m_cgd, "gp", new string[] { GMVname, GMVname }, FT, m_G25M.m_name); } } }
/// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["gmv"] = m_specification.m_GMV; argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["targetFuncReturnsFloat"] = m_specification.IsFloatType(m_fgs.ReturnTypeName); argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["reverseFuncName"] = m_reverseFuncName[FT.type]; argTable["gpFuncName"] = m_gpFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testRandomGMV", argTable); } return(testFuncNames); } // end of WriteTestFunction()
/// <summary> /// Writes a increment or decrement function. /// (not based on CASN parts code, but put here anyway). /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="increment"></param> public static string WriteIncrementFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, bool increment) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.CANSparts.GetIncrementCode(S, cgd, FT, FAI, fgs.RETURN_ARG_NAME, increment); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); return(CF.OutputName); }
/// <summary> /// Writes any addition or subtraction function for general multivectors, /// based on CASN parts code. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="funcType">ADD, SUB or HP</param> /// <returns>Full name of generated function.</returns> public static string WriteAddSubHpFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.CANSparts.ADD_SUB_HP_TYPE funcType) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.CANSparts.GetAddSubtractHpCode(S, cgd, FT, funcType, FAI, fgs.RETURN_ARG_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value string funcName = CF.OutputName; //if (S.OutputC()) // funcName = FT.GetMangledName(S, funcName); // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return funcName; }
/// <summary> /// Writes 'set()' declarations of a GOM class to 'SB'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'GOM'.</param> /// <param name="gom">The general outermorphism for which the class should be written.</param> /// <param name="className">Mangled name of GOM class.</param> /// <param name="rangeVectorSMVname">The name of the SMV which can represent a column of the OM.</param> public static void WriteSetDeclarations(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GOM gom, string className, string rangeVectorSMVname) { cgd.m_cog.EmitTemplate(SB, "GOMsetDecl", "S=", S, "FT=", FT, "className=", className, "rangeVectorSMVname=", rangeVectorSMVname); { // extra code for per-grade-per-basisblade functions to set OM from vectors SB.AppendLine("\tprivate:"); bool matrixMode = false; // this value is irrelevant at this point string typeName = FT.GetMangledName(S, gom.Name); string prefix = typeName + "::"; string[] funcNames = G25.CG.Shared.OMinit.GetSetFromLowerGradeFunctionNames(S, FT, matrixMode); for (int g = 1; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { string funcName = funcNames[g] + "_" + d; if (funcName.IndexOf(prefix) == 0) { funcName = funcName.Substring(prefix.Length); } SB.AppendLine("\tvoid " + funcName + "();"); } } SB.AppendLine("\tpublic:"); } }
/// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["cgaPointName"] = FT.GetMangledName(m_specification, m_fgs.m_returnTypeName); argTable["cgaPointType"] = m_specification.GetType(m_fgs.m_returnTypeName); if (IsFlatPointBased(m_specification, m_fgs, FT)) { argTable["flatPointName"] = FT.GetMangledName(m_specification, m_flatPointType.GetName()); argTable["opFuncName"] = m_opFuncName[FT.type]; argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["randomFpName"] = m_randomFlatPointFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testCgaPointFromFlatPoint", argTable); } else { argTable["coordBased"] = IsCoordBased(m_specification, m_fgs, FT); argTable["vectorBased"] = IsVectorBased(m_specification, m_fgs, FT); argTable["random"] = IsRandom(m_specification, m_fgs); argTable["vectorName"] = (m_vectorType == null) ? "not_set" : FT.GetMangledName(m_specification, m_vectorType.GetName()); argTable["randomVectorFuncName"] = m_randomVectorFuncName[FT.type]; argTable["spFuncName"] = m_spFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testCgaPoint", argTable); } } return(testFuncNames); } // end of WriteTestFunction()
public static void WriteSetCopy(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) { declSB.AppendLine(); } defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_set"); bool mustCast = false; const int NB_ARGS = 1; string srcName = "src"; bool srcPtr = S.OutputC(); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { som.Name }, new String[] { srcName }, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); } // setup instructions List <G25.CG.Shared.Instruction> I = new List <G25.CG.Shared.Instruction>(); { int nbTabs = 1; mustCast = false; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = (S.OutputCppOrC()); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.Multivector srcValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, srcName, srcPtr); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, srcValue, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Copies " + typeName + ".");; bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); if (m_gmvFunc) // GMV test { testFuncNames.Add(testFuncName); m_cgd.m_cog.EmitTemplate(defSB, "testZeroGMV", "S=", m_specification, "FT=", FT, "gmvName=", FT.GetMangledName(m_specification, m_specification.m_GMV.Name), "testFuncName=", testFuncName, "targetFuncName=", m_funcName[FT.type], "randomScalarFuncName=", m_randomScalarFuncName[FT.type], "randomVersorFuncName=", m_randomVersorFuncName[FT.type] ); } else if (m_smv != null) // SMV test { testFuncNames.Add(testFuncName); m_cgd.m_cog.EmitTemplate(defSB, "testZeroSMV", "S=", m_specification, "FT=", FT, "smv=", m_smv, "smvName=", FT.GetMangledName(m_specification, m_smv.Name), "testFuncName=", testFuncName, "targetFuncName=", m_funcName[FT.type], "randomScalarFuncName=", m_randomScalarFuncName[FT.type], "randomSmvFuncName=", m_randomSmvFuncName[FT.type] ); } } return(testFuncNames); }
/// <summary> /// Writes the testing function for 'F' to 'm_defSB'. /// The generated function returns success (1) or failure (0). /// </summary> /// <returns>The list of name name of the int() function which tests the function.</returns> public override List <string> WriteTestFunction() { StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; List <string> testFuncNames = new List <string>(); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); if (m_smv1.CanConvertToGmv(m_specification) && m_smv2.CanConvertToGmv(m_specification)) { string testFuncName = Util.GetTestingFunctionName(m_specification, m_cgd, m_funcName[FT.type]); testFuncNames.Add(testFuncName); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = m_specification; argTable["FT"] = FT; argTable["testFuncName"] = testFuncName; argTable["targetFuncName"] = m_funcName[FT.type]; argTable["squared"] = IsDistance2(m_fgs); argTable["gmvName"] = FT.GetMangledName(m_specification, m_specification.m_GMV.Name); argTable["arg1TypeName"] = FT.GetMangledName(m_specification, m_smv1.Name); argTable["arg2TypeName"] = FT.GetMangledName(m_specification, m_smv2.Name); argTable["cgaPointName"] = FT.GetMangledName(m_specification, m_cgaPointTypeName[FT.type]); argTable["cgaPointType"] = m_specification.GetType(m_cgaPointTypeName[FT.type]); argTable["sqrt"] = CodeUtil.OpNameToLangString(m_specification, FT, UnaryScalarOp.SQRT); argTable["fabs"] = CodeUtil.OpNameToLangString(m_specification, FT, UnaryScalarOp.ABS); argTable["randomScalarFuncName"] = m_randomScalarFuncName[FT.type]; argTable["c3gaPointFuncName"] = m_cgaPointFuncName[FT.type]; m_cgd.m_cog.EmitTemplate(defSB, "testCgaPointDistance", argTable); } } return(testFuncNames); } // end of WriteTestFunction()
private static void WriteDefinition(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Constant C) { // assume only SMV constants for now G25.SMV smv = C.Type as G25.SMV; ConstantSMV Csmv = C as ConstantSMV; // MANGLED_TYPENAME MANGLED_CONSTANT_NAME = {...} SB.Append(FT.GetMangledName(S, C.Type.GetName())); SB.Append(" "); SB.Append(FT.GetMangledName(S, C.Name)); SB.Append(" = {"); if (smv.NbNonConstBasisBlade == 0) { // 'C' does not allow empty structs, so there is a filler that must be initialized SB.Append("0"); } else { if (S.m_coordStorage == COORD_STORAGE.ARRAY) { SB.Append("{"); } for (int c = 0; c < smv.NbNonConstBasisBlade; c++) { if (c > 0) { SB.Append(", "); } SB.Append(FT.DoubleToString(S, Csmv.Value[c])); } if (S.m_coordStorage == COORD_STORAGE.ARRAY) { SB.Append("}"); } } SB.AppendLine("};"); }
} // end of WriteLargestCoordinateFunctions() /// <summary> /// Writes getters and setters for the SMV coordinates.. /// </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 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteGetSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { int nbTabs = 1; string className = FT.GetMangledName(S, smv.Name); // for variable coordinates: for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); string name = smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames); string accessName = G25.CG.Shared.SmvUtil.GetCoordAccessString(S, smv, i); // get string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + name + "() { return " + accessName + ";}"); // set string setComment = "Sets the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(setComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " void " + G25.CG.Shared.Main.SETTER_PREFIX + name + "(" + FT.type + " " + name + ") { " + accessName + " = " + name + ";}"); } // for constant coordinates: for (int i = 0; i < smv.NbConstBasisBlade; i++) { RefGA.BasisBlade B = smv.ConstBasisBlade(i); // get string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, smv.ConstBasisBladeValue(i)) + ";}"); } // write a getter for the scalar which returns 0 if no scalar coordinate is present if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; string getComment = "Returns the scalar coordinate (which is always 0)."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, 0.0) + ";}"); } // getter for the coordinates (stored in array) if ((S.m_coordStorage == COORD_STORAGE.ARRAY) && (smv.NbNonConstBasisBlade > 0)) { string constantName = G25.CG.Shared.SmvUtil.GetCoordinateOrderConstant(S, smv); string COORD_ORDER = "coordOrder"; new G25.CG.Shared.Comment("Returns array of coordinates."). SetParamComment(COORD_ORDER, "pass the value '" + className + "." + constantName + "'"). Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + "[] c(" + G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM + " " + COORD_ORDER + ") { return m_c;}"); } }
/// <summary> /// Writes any code to extract a grade part. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="gradeIdx">Grade to be selected (use -1 for user-specified).</param> public static string WriteGradeFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, int gradeIdx) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: const string GROUP_BITMAP_NAME = "groupBitmap"; string code = G25.CG.Shared.CANSparts.GetGradeCode(S, cgd, FT, gradeIdx, FAI, fgs.RETURN_ARG_NAME, GROUP_BITMAP_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); string funcName = CF.OutputName; //if (S.OutputC()) // funcName = FT.GetMangledName(S, funcName); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } //StringBuilder tmpSB = new StringBuilder(); // G25.CG.Shared.Functions.WriteFunction() writes to this SB first so we can add the grade index if required // write function G25.CG.Shared.CGdata tmpCgd = new G25.CG.Shared.CGdata(cgd); bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, tmpCgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); if (gradeIdx < 0) // hack: if grade is func arg, then add it: { // add extra argument (int) to select the grade //if (S.OutputCppOrC()) // tmpCgd.m_declSB = AddGradeArg(S, tmpCgd.m_declSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); //tmpCgd.m_defSB = AddGradeArg(S, tmpCgd.m_defSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); //tmpCgd.m_inlineDefSB = AddGradeArg(S, tmpCgd.m_inlineDefSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); } cgd.m_declSB.Append(tmpCgd.m_declSB); cgd.m_defSB.Append(tmpCgd.m_defSB); cgd.m_inlineDefSB.Append(tmpCgd.m_inlineDefSB); return(funcName); } // end of WriteGradeFunction()
/// <summary> /// Writes the definition of an GMV class to 'SB' (including comments). /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="gmv">The general multivector for which the struct should be written.</param> public static void WriteGMVclass(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GMV gmv) { SB.AppendLine(""); WriteComment(SB, S, cgd, FT, gmv); string className = FT.GetMangledName(S, gmv.Name); SB.AppendLine("class " + className); SB.AppendLine("{"); WriteMemberVariables(SB, S, cgd, FT, gmv); SB.AppendLine("public:"); WriteFloatType(SB, S, cgd, FT, gmv, className); WriteConstructors(SB, S, cgd, FT, gmv, className); WriteAssignmentOperators(SB, S, cgd, FT, gmv, className); WriteSetDeclarations(SB, S, cgd, FT, gmv, className); WriteGetCoord(S, cgd, FT, SB); WriteSetCoord(S, cgd, FT, SB); WriteCompressExpandDeclarations(SB, S, cgd, FT, gmv, className); WriteLargestCoordinateDeclarations(SB, S, cgd, FT, gmv, className); // grade usage SB.AppendLine("\t/// returns grade/group."); SB.AppendLine("\tinline int gu() const {return m_gu;}"); WriteToString(SB, S, cgd, FT, gmv, className); // function which returns pointer to some array of zeros SB.AppendLine("public:"); SB.AppendLine("\tinline " + FT.type + " const *nullFloats() const {"); SB.AppendLine("\t\tstatic " + FT.type + " *nf = NULL;"); SB.AppendLine("\t\treturn (nf == NULL) ? (nf = new " + FT.type + "[" + S.m_GMV.NbCoordinates + "]) : nf;"); SB.AppendLine("\t}"); // function for setting grade/group usage, reallocting memory cgd.m_cog.EmitTemplate(SB, "GMVsetGroupUsage", "S=", S, "FT=", FT, "className=", className, "gmv=", gmv); // function for allocating a group cgd.m_cog.EmitTemplate(SB, "GMVallocateGroups", "S=", S, "FT=", FT, "className=", className, "gmv=", gmv); SB.AppendLine("}; // end of class " + className); } // end of WriteGMVclass()
/// <summary> /// Writes the <c>defines</c> for indices of the smv struct to 'SB'. For example, <c>define VECTOR_E1 0</c>. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names.</param> /// <param name="FT"></param> /// <param name="smv">The specialized multivector for which the coordinate indices should be written.</param> public static void WriteSMVcoordIndices(StringBuilder SB, Specification S, FloatType FT, G25.SMV smv) { string className = FT.GetMangledName(S, smv.Name); SB.AppendLine("\t/// Array indices of " + className + " coordinates."); SB.AppendLine("\ttypedef enum {"); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine("\t\t/// index of coordinate for " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " in " + className); SB.AppendLine("\t\t" + GetCoordIndexDefine(S, FT, smv, i) + " = " + i + ", "); } SB.AppendLine("\t} ArrayIndex;"); }
/// <summary> /// Writes any geometric product based product for general multivectors, /// based on gp parts code. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="declOnly"></param> /// <param name="productType"></param> /// <returns>name of generated function</returns> public static string WriteGMVgpFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.GPparts.ProductTypes productType) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.GPparts.GetGPcode(S, cgd, FT, M, productType, FAI, fgs.RETURN_ARG_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = null; G25.CG.Shared.FuncArgInfo returnArgument = null; if (productType == G25.CG.Shared.GPparts.ProductTypes.SCALAR_PRODUCT) { // return scalar returnTypeName = FT.type; } else { // return GMV (in C, via 'return argument') returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } } string funcName = CF.OutputName; // FAI[0].MangledTypeName; //CF.ArgumentTypeNames[0] = CF.ArgumentTypeNames[0] + G25.CG.Shared.Main.IF_SUFFIX; // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return(funcName); } // end of WriteGMVgpFunction
/// <summary> /// Writes a function to set an SOM struct/class to identity /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> /// <param name="som"></param> public static void WriteSetIdentity(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) { declSB.AppendLine(); } defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "setIdentity", "_setIdentity"); bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", null, null, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); } // setup instructions List <G25.CG.Shared.Instruction> I = new List <G25.CG.Shared.Instruction>(); { int nbTabs = 1; mustCast = false; string valueName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool valuePtr = S.OutputCppOrC(); bool declareValue = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, new RefGA.Multivector(som.DomainForGrade(g)[c]), valueName, valuePtr, declareValue)); } } } Comment comment = new Comment("Sets " + typeName + " to identity."); bool writeDecl = S.OutputC(); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, new G25.CG.Shared.FuncArgInfo[0], I, comment, writeDecl); }
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 string[] GetSetFromLowerGradeFunctionNames(Specification S, FloatType FT, bool matrixMode) { G25.GOM gom = S.m_GOM; // generate function names for all grades (basis blade names not included) string typeName = FT.GetMangledName(S, gom.Name); string[] funcNames = new string[gom.Domain.Length]; for (int g = 1; g < gom.Domain.Length; g++) { string nameC = (g > 1) ? "_set" : ((matrixMode) ? "_setMatrix" : "_setVectorImages"); string suffix = (g > 1) ? ("_grade_" + g) : ""; funcNames[g] = GetFunctionName(S, typeName, "set" + suffix, nameC + suffix); } return(funcNames); }
} // end of WriteGMVigpFunction /// <summary> /// Writes any norm function for general multivectors, based on gp parts code. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="declOnly"></param> /// <param name="squared"></param> /// <returns>name of generated function.</returns> public static string WriteGMVnormFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, bool squared) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); string funcName = CF.OutputName; // get return info G25.SMV returnType = null; string returnTypeName = null; G25.CG.Shared.FuncArgInfo returnArgument = null; { // try to get scalar type returnType = S.GetScalarSMV(); if (returnType == null) { returnTypeName = FT.type; } else { if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, returnType.Name, false); // false = compute value } returnTypeName = FT.GetMangledName(S, returnType.GetName()); } } // write this function: string code = G25.CG.Shared.GPparts.GetNormCode(S, cgd, FT, M, squared, FAI, returnType, G25.fgs.RETURN_ARG_NAME); // add the verbatim code I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return(funcName); } // end of WriteGMVnormFunction
/// <summary> /// Writes the <c>defines</c> for indices of the smv struct to 'SB'. For example, <c>define VECTOR_E1 0</c>. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names.</param> /// <param name="FT"></param> /// <param name="smv">The specialized multivector for which the coordinate indices should be written.</param> public static void WriteSMVcoordIndices(StringBuilder SB, Specification S, FloatType FT, G25.SMV smv) { string className = FT.GetMangledName(S, smv.Name); int nbTabs = 1; new G25.CG.Shared.Comment("Array indices of " + className + " coordinates.").Write(SB, S, nbTabs); string AccessModifier = Keywords.ConstAccessModifier(S); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine(); new G25.CG.Shared.Comment("index of coordinate for " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " in " + className).Write(SB, S, nbTabs); SB.AppendLine("\tpublic " + AccessModifier + " int " + GetCoordIndexDefine(S, FT, smv, i) + " = " + i + ";"); } }
public static void WriteSetMatrix(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som, bool transpose) { int NB_ARGS = 1; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; argTypes[0] = FT.type; argNames[0] = "M"; // construct image values RefGA.Multivector[] imageValue = new RefGA.Multivector[som.DomainVectors.Length]; for (int d = 0; d < som.DomainVectors.Length; d++) { //imageValue[d] = RefGA.Multivector.ZERO; RefGA.BasisBlade[] IV = new RefGA.BasisBlade[som.RangeVectors.Length]; for (int r = 0; r < som.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * som.RangeVectors.Length + r) : (r * som.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(som.RangeVectors[r].bitmap, 1.0, entryName); } imageValue[d] = new RefGA.Multivector(IV); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setMatrix"); if (transpose) funcName = funcName + "Transpose"; //argNames[0] = "*" + argNames[0]; // quick hack: add pointer to name instead of type! G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (S.OutputCppOrC()) F.m_argumentPtr[0] = true; else F.m_argumentArr[0] = true; bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c]; RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade for (uint v = 0; v < som.DomainVectors.Length; v++) { if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0) { value = RefGA.Multivector.op(value, imageValue[v]); } } I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix."); bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes a function to set a GOM struct according to vector images, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float type.</param> /// <param name="matrixMode">When true, generates code for setting from matrix instead of vector images.</param> /// <param name="transpose">When this parameter is true and <c>matrixMode</c> is true, generates code for setting from transpose matrix.</param> public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, bool matrixMode, bool transpose) { G25.GOM gom = S.m_GOM; // get the 'plan' on how to initialize all domain basis blades efficiently: uint[][][] plan = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsPlan(S, gom); double[][] signs = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsSigns(S, gom, plan); // get range vector type G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, gom); // setup array of arguments, function specification, etc int NB_ARGS = (matrixMode) ? 1 : gom.DomainVectors.Length; string[] argTypes = new string[NB_ARGS], argNames = new string[NB_ARGS]; RefGA.Multivector[] symbolicBBvalues = new RefGA.Multivector[1 << S.m_dimension]; // symbolic basis blade values go here if (matrixMode) { argTypes[0] = FT.type; argNames[0] = "M"; // convert matrix columns to symbolic Multivector values for (int d = 0; d < gom.DomainVectors.Length; d++) { RefGA.BasisBlade[] IV = new RefGA.BasisBlade[gom.RangeVectors.Length]; for (int r = 0; r < gom.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * gom.RangeVectors.Length + r) : (r * gom.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(gom.RangeVectors[r].bitmap, 1.0, entryName); } symbolicBBvalues[gom.DomainVectors[d].bitmap] = new RefGA.Multivector(IV); } } else { for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + gom.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = S.OutputC(); symbolicBBvalues[gom.DomainVectors[d].bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } } // generate function names for all grades (basis blade names not included) string typeName = FT.GetMangledName(S, gom.Name); string[] funcNames = GetSetFromLowerGradeFunctionNames(S, FT, matrixMode); // setup instructions (for main function, and subfunctions for grades) List<G25.CG.Shared.Instruction> mainI = new List<G25.CG.Shared.Instruction>(); List<G25.CG.Shared.Instruction>[] bladeI = new List<G25.CG.Shared.Instruction>[1 << S.m_dimension]; { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { G25.SMVOM smvOM = gom.DomainSmvForGrade(g)[d]; RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; if (g > 1) { bladeI[domainBlade.bitmap] = new List<G25.CG.Shared.Instruction>(); string funcCallCode = funcNames[g] + "_" + d + "("; if (S.OutputC()) funcCallCode += G25.fgs.RETURN_ARG_NAME; funcCallCode += ");"; mainI.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, funcCallCode)); } // follow the plan RefGA.Multivector value = new RefGA.Multivector(signs[g][d]); uint[] P = plan[g][d]; for (int p = 0; p < P.Length; p++) value = RefGA.Multivector.op(value, symbolicBBvalues[P[p]]); // add instructions List<G25.CG.Shared.Instruction> I = (g == 1) ? mainI : bladeI[domainBlade.bitmap]; I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); // store symbolic value symbolicBBvalues[domainBlade.bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, dstName, dstPtr); } } } // output grade > 1 functions if (cgd.generateOmInitCode(FT.type)) { for (int g = 2; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; string funcName = funcNames[g] + "_" + d; G25.fgs F = new G25.fgs(funcName, funcName, "", new string[0], new string[0], new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options //F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); int nbArgs = 0; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; comment = new Comment("Sets grade " + g + " part of outermorphism matrix based on lower grade parts."); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcName, returnArgument, FAI, bladeI[domainBlade.bitmap], comment, writeDecl); } } } { // output grade 1 function G25.fgs F = new G25.fgs(funcNames[1], funcNames[1], "", argTypes, argNames, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (matrixMode) { F.m_argumentPtr[0] = S.OutputCppOrC(); F.m_argumentArr[0] = S.OutputCSharpOrJava(); } bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; if (!matrixMode) comment = new Comment("Sets " + typeName + " from images of the domain vectors."); else comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix"); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcNames[1], returnArgument, FAI, mainI, comment, writeDecl); } }
public static void WriteSetCopy(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) declSB.AppendLine(); defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_set"); bool mustCast = false; const int NB_ARGS = 1; string srcName = "src"; bool srcPtr = S.OutputC(); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { som.Name }, new String[] { srcName }, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { int nbTabs = 1; mustCast = false; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = (S.OutputCppOrC()); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.Multivector srcValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, srcName, srcPtr); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, srcValue, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Copies " + typeName + "."); ; bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes a function to set an SOM struct/class to identity /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> /// <param name="som"></param> public static void WriteSetIdentity(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) declSB.AppendLine(); defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "setIdentity", "_setIdentity"); bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", null, null, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { int nbTabs = 1; mustCast = false; string valueName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool valuePtr = S.OutputCppOrC(); bool declareValue = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, new RefGA.Multivector(som.DomainForGrade(g)[c]), valueName, valuePtr, declareValue)); } } } Comment comment = new Comment("Sets " + typeName + " to identity."); bool writeDecl = S.OutputC(); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, new G25.CG.Shared.FuncArgInfo[0], I, comment, writeDecl); }
/// <summary> /// Writes the SMV class to 'SB' (including comments). /// </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 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> /// <param name="emitCoordIndices">Whether to emit constants for array indices to coordinates.</param> public static void WriteSMVclass(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv, bool emitCoordIndices) { string className = FT.GetMangledName(S, smv.Name); SB.AppendLine(""); WriteComment(SB, S, cgd, FT, smv, emitCoordIndices); // typedef SB.AppendLine("class " + className); SB.AppendLine("{"); WriteMemberVariables(SB, S, cgd, FT, smv); SB.AppendLine("public:"); WriteFloatType(SB, S, cgd, FT, smv, className); if (emitCoordIndices) WriteSMVcoordIndices(SB, S, FT, smv); WriteCoordinateOrder(SB, S, FT, smv); WriteConstructors(SB, S, cgd, FT, smv); WriteAssignmentOperators(SB, S, cgd, FT, smv); WriteSetDeclarations(SB, S, cgd, FT, smv); WriteLargestCoordinateDeclarations(SB, S, cgd, FT, smv); WriteToString(SB, S, cgd, FT, smv); SB.AppendLine(""); WriteGetSetCoord(SB, S, cgd, FT, smv); SB.AppendLine("}; // end of class " + className); }
public static string[] GetSetFromLowerGradeFunctionNames(Specification S, FloatType FT, bool matrixMode) { G25.GOM gom = S.m_GOM; // generate function names for all grades (basis blade names not included) string typeName = FT.GetMangledName(S, gom.Name); string[] funcNames = new string[gom.Domain.Length]; for (int g = 1; g < gom.Domain.Length; g++) { string nameC = (g > 1) ? "_set" : ((matrixMode) ? "_setMatrix" : "_setVectorImages"); string suffix = (g > 1) ? ("_grade_" + g) : ""; funcNames[g] = GetFunctionName(S, typeName, "set" + suffix, nameC + suffix); } return funcNames; }
protected void WriteNormReturnsScalar(FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, String funcName, G25.SMV scalarSMV) { StringBuilder declSB = m_cgd.m_declSB; StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; string inlineStr = G25.CG.Shared.Util.GetInlineString(m_specification, m_specification.m_inlineFunctions, " "); string refPtrStr = ""; if (m_specification.OutputC()) refPtrStr = "*"; else if (m_specification.OutputCpp()) refPtrStr = "&"; string ACCESS = ""; if (m_specification.OutputJava()) ACCESS = "public final static "; else if (m_specification.OutputCSharp()) ACCESS = "public static "; string VAR_MOD = ""; if (m_specification.OutputCppOrC()) VAR_MOD = "const "; if (m_specification.OutputJava()) VAR_MOD = "final "; string funcDecl = FT.type + " " + funcName + G25.CG.Shared.CANSparts.RETURNS_SCALAR + "(" + VAR_MOD + FAI[0].MangledTypeName + " " + refPtrStr + FAI[0].Name + ")"; string comment = "internal conversion function (this is just a pass through)"; int nbTabs = 0; if (m_specification.OutputCppOrC()) { new Comment(comment).Write(declSB, m_specification, nbTabs); declSB.Append(funcDecl); declSB.AppendLine(";"); } else new Comment(comment).Write(defSB, m_specification, nbTabs); defSB.Append(inlineStr + ACCESS + funcDecl); defSB.AppendLine(" {"); if (m_specification.OutputC()) { defSB.AppendLine("\t" + FT.GetMangledName(m_specification, scalarSMV.Name) + " tmp;"); defSB.AppendLine("\t" + funcName + "(&tmp, " + FAI[0].Name + ");"); } else if (m_specification.OutputCpp()) { defSB.AppendLine("\t" + FT.GetMangledName(m_specification, scalarSMV.Name) + " tmp(" + funcName + "(" + FAI[0].Name + "));"); } else { defSB.AppendLine("\t" + FT.GetMangledName(m_specification, scalarSMV.Name) + " tmp = " + funcName + "(" + FAI[0].Name + ");"); } string[] accessStr; { bool ptr = false; accessStr = G25.CG.Shared.CodeUtil.GetAccessStr(m_specification, scalarSMV, "tmp", ptr); } defSB.AppendLine("\treturn " + accessStr[0] + ";"); defSB.AppendLine("}"); }
/* /// <summary> /// Writes the function to get the array of coordinates. /// Does nothing when coordinate storage is not array based or when the type has no variable coordinates. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names.</param> /// <param name="FT"></param> /// <param name="smv">The specialized multivector for which the coordinate indices should be written.</param> public static void WriteGetCoordinates(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { if (S.m_coordStorage != COORD_STORAGE.ARRAY) return; if (smv.NbNonConstBasisBlade == 0) return; //string typeName = G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM; string constantName = G25.CG.Shared.SmvUtil.GetCoordinateOrderConstant(S, smv); cgd.m_cog.EmitTemplate(SB, "SMVgetCoords", "FT=", FT, "COORD_TYPE_STRING=", constantName); }*/ /// <summary> /// Writes the implementation of the multivector interface. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> public static void WriteMultivectorInterface(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { string gmvName = FT.GetMangledName(S, S.m_GMV.Name); cgd.m_cog.EmitTemplate(SB, "SMVmvInterfaceImpl", "gmvName=", gmvName); }
public static string GetMvInterfaceName(Specification S, FloatType FT) { return FT.GetMangledName(S, S.m_GMV.Name) + G25.CG.Shared.Main.IF_SUFFIX; }
/// <summary> /// Writes any norm function for general multivectors, based on gp parts code. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="declOnly"></param> /// <param name="squared"></param> /// <returns>name of generated function.</returns> public static string WriteGMVnormFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, bool squared) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); string funcName = CF.OutputName; // get return info G25.SMV returnType = null; string returnTypeName = null; G25.CG.Shared.FuncArgInfo returnArgument = null; { // try to get scalar type returnType = S.GetScalarSMV(); if (returnType == null) { returnTypeName = FT.type; } else { if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, returnType.Name, false); // false = compute value returnTypeName = FT.GetMangledName(S, returnType.GetName()); } } // write this function: string code = G25.CG.Shared.GPparts.GetNormCode(S, cgd, FT, M, squared, FAI, returnType, G25.fgs.RETURN_ARG_NAME); // add the verbatim code I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return funcName; }
/// <summary> /// Writes getters and setters for the SMV coordinates.. /// </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 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteGetSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { int nbTabs = 1; string className = FT.GetMangledName(S, smv.Name); // for variable coordinates: for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); string name = smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames); string accessName = G25.CG.Shared.SmvUtil.GetCoordAccessString(S, smv, i); // get string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + name + "() { return " + accessName + ";}"); // set string setComment = "Sets the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(setComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " void " + G25.CG.Shared.Main.SETTER_PREFIX + name + "(" + FT.type + " " + name + ") { " + accessName + " = " + name + ";}"); } // for constant coordinates: for (int i = 0; i < smv.NbConstBasisBlade; i++) { RefGA.BasisBlade B = smv.ConstBasisBlade(i); // get string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, smv.ConstBasisBladeValue(i)) + ";}"); } // write a getter for the scalar which returns 0 if no scalar coordinate is present if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; string getComment = "Returns the scalar coordinate (which is always 0)."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, 0.0) + ";}"); } // getter for the coordinates (stored in array) if ((S.m_coordStorage == COORD_STORAGE.ARRAY) && (smv.NbNonConstBasisBlade > 0)) { string constantName = G25.CG.Shared.SmvUtil.GetCoordinateOrderConstant(S, smv); string COORD_ORDER = "coordOrder"; new G25.CG.Shared.Comment("Returns array of coordinates."). SetParamComment(COORD_ORDER, "pass the value '" + className + "." + constantName + "'"). Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + "[] c(" + G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM + " " + COORD_ORDER + ") { return m_c;}"); } }
/// <summary> /// Writes functions to copy SMVs to GMVs /// </summary> /// <param name="SB">Where the output goes.</param> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> public static void WriteSMVtoGMVcopy(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT) { int nbTabs; G25.GMV gmv = S.m_GMV; bool gmvParityPure = (S.m_GMV.MemoryAllocationMethod == G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE); //string dstClassName = FT.GetMangledName(S, gmv.Name); for (int s = 0; s < S.m_SMV.Count; s++) { G25.SMV smv = S.m_SMV[s]; // do not generate converter if the GMV cannot hold the type if (gmvParityPure && (!smv.IsParityPure())) continue; string srcClassName = FT.GetMangledName(S, smv.Name); SB.AppendLine(); nbTabs = 1; new G25.CG.Shared.Comment("sets this to " + srcClassName + " value.").Write(SB, S, nbTabs); string funcName = GetSetFuncName(S); string funcDecl = "\tpublic void " + funcName + "(" + srcClassName + " src)"; SB.Append(funcDecl); { SB.AppendLine(" {"); // get a dictionary which tells you for each basis blade of 'gmv' where it is in 'smv' Dictionary<Tuple<int, int>, Tuple<int, int>> D = G25.MV.GetCoordMap(smv, gmv); // convert SMV to symbolic Multivector: bool smvPtr = false; RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, "src", smvPtr); // find out which groups are present StringBuilder guSB = new StringBuilder(); int gu = 0; foreach (KeyValuePair<Tuple<int, int>, Tuple<int, int>> KVP in D) { int bit = 1 << KVP.Value.Value1; if ((gu & bit) == 0) { gu |= 1 << KVP.Value.Value1; if (guSB.Length > 0) guSB.Append("|"); guSB.Append("GroupBitmap.GROUP_" + KVP.Value.Value1); } } // generate the code to set group usage: SB.AppendLine("\t\t" + GetAllocateGroupsString(S) + "(" + guSB.ToString() + ");"); // a helper pointer string dstArrName = "ptr"; SB.AppendLine("\t\t" + FT.type + "[] " + dstArrName + ";"); // for each used group, generate the assignment code for (int g = 0; (1 << g) <= gu; g++) { if (((1 << g) & gu) != 0) { SB.AppendLine(); SB.AppendLine("\t\tptr = m_c[" + g + "];"); int dstBaseIdx = 0; bool mustCast = false; nbTabs = 2; bool writeZeros = true; string str = G25.CG.Shared.CodeUtil.GenerateGMVassignmentCode(S, FT, mustCast, gmv, dstArrName, g, dstBaseIdx, value, nbTabs, writeZeros); SB.Append(str); } } if (S.m_reportUsage) { SB.AppendLine("\t\tm_t = " + G25.CG.CSJ.GMV.SMV_TYPE + "." + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, smv.Name) + ";"); } SB.AppendLine("\t}"); } } // end of loop over all SMVs }
/// <summary> /// Writes the definition of an SOM struct to 'SB' (including comments). /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="som">The general outermorphism for which the struct should be written.</param> public static void WriteSOMstruct(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { SB.AppendLine(""); { // comments for type: SB.AppendLine("/**"); SB.AppendLine(" * This struct can hold a specialized outermorphism."); SB.AppendLine(" * "); SB.AppendLine(" * The coordinates are stored in type " + FT.type + "."); SB.AppendLine(" * "); SB.AppendLine(" * There are " + som.Domain.Length + " matrices, one for each grade."); SB.AppendLine(" * The columns of these matrices are the range of the outermorphism."); SB.AppendLine(" * Matrices are stored in row-major order. So the coordinates of rows are stored contiguously."); for (int g = 1; g < som.Domain.Length; g++) // start at '1' in order to skip scalar grade { SB.Append(" * Domain grade " + g + ": "); for (int i = 0; i < som.DomainForGrade(g).Length; i++) { if (i > 0) SB.Append(", "); SB.Append(som.DomainForGrade(g)[i].ToString(S.m_basisVectorNames)); } SB.AppendLine("."); } SB.AppendLine(" * "); if (!som.DomainAndRangeAreEqual()) { for (int g = 1; g < som.Range.Length; g++) // start at '1' in order to skip scalar grade { SB.Append(" * Range grade " + g + ": "); for (int i = 0; i < som.RangeForGrade(g).Length; i++) { if (i > 0) SB.Append(", "); SB.Append(som.RangeForGrade(g)[i].ToString(S.m_basisVectorNames)); } SB.AppendLine("."); } } else SB.AppendLine(" * The range and domain are equal."); SB.AppendLine(" * "); SB.AppendLine(" */"); } // end of comment // typedef SB.AppendLine("typedef struct "); SB.AppendLine("{"); for (int g = 1; g < som.Domain.Length; g++) // start at '1' in order to skip scalar grade { if (!som.EmptyGrade(g)) { SB.AppendLine("\t/** Matrix for grade " + g + "; the size is " + som.DomainForGrade(g).Length + " x " + som.RangeForGrade(g).Length + " */"); SB.AppendLine("\t" + FT.type + " m" + g + "[" + som.DomainForGrade(g).Length * som.RangeForGrade(g).Length + "];"); } } SB.AppendLine("} " + FT.GetMangledName(S, som.Name) + ";"); }
/// <summary> /// Writes the SMV class comment 'SB'. /// </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 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> /// <param name="emitCoordIndices">Whether to emit constants for array indices to coordinates.</param> public static void WriteComment(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv, bool emitCoordIndices) { SB.AppendLine("/**"); SB.AppendLine(" * This class can hold a specialized multivector of type " + FT.GetMangledName(S, smv.Name) + "."); SB.AppendLine(" * "); SB.AppendLine(" * The coordinates are stored in type " + FT.type + "."); SB.AppendLine(" * "); if (smv.NbNonConstBasisBlade > 0) { SB.AppendLine(" * The variable non-zero coordinates are:"); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine(" * - coordinate " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " (array index: " + GetCoordIndexDefine(S, FT, smv, i) + " = " + i + ")"); } } else SB.AppendLine(" * The type is constant."); SB.AppendLine(" * "); if (smv.NbConstBasisBlade > 0) { SB.AppendLine(" * The constant non-zero coordinates are:"); for (int i = 0; i < smv.NbConstBasisBlade; i++) SB.AppendLine(" * - " + smv.ConstBasisBlade(i).ToString(S.m_basisVectorNames) + " = " + smv.ConstBasisBladeValue(i).ToString()); } else SB.AppendLine(" * The type has no constant coordinates."); SB.AppendLine(" * "); if ((smv.Comment != null) && (smv.Comment.Length > 0)) { SB.AppendLine(" * "); SB.AppendLine(" * " + smv.Comment); } SB.AppendLine(" */"); }
/// <summary> /// Writes any code to extract a grade part. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="gradeIdx">Grade to be selected (use -1 for user-specified).</param> public static string WriteGradeFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, int gradeIdx) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: const string GROUP_BITMAP_NAME = "groupBitmap"; string code = G25.CG.Shared.CANSparts.GetGradeCode(S, cgd, FT, gradeIdx, FAI, fgs.RETURN_ARG_NAME, GROUP_BITMAP_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); string funcName = CF.OutputName; //if (S.OutputC()) // funcName = FT.GetMangledName(S, funcName); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value //StringBuilder tmpSB = new StringBuilder(); // G25.CG.Shared.Functions.WriteFunction() writes to this SB first so we can add the grade index if required // write function G25.CG.Shared.CGdata tmpCgd = new G25.CG.Shared.CGdata(cgd); bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, tmpCgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); if (gradeIdx < 0) // hack: if grade is func arg, then add it: { // add extra argument (int) to select the grade //if (S.OutputCppOrC()) // tmpCgd.m_declSB = AddGradeArg(S, tmpCgd.m_declSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); //tmpCgd.m_defSB = AddGradeArg(S, tmpCgd.m_defSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); //tmpCgd.m_inlineDefSB = AddGradeArg(S, tmpCgd.m_inlineDefSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); } cgd.m_declSB.Append(tmpCgd.m_declSB); cgd.m_defSB.Append(tmpCgd.m_defSB); cgd.m_inlineDefSB.Append(tmpCgd.m_inlineDefSB); return funcName; }
/// <summary> /// Writes the definition of an GMV class to 'SB' (including comments). /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="gmv">The general multivector for which the struct should be written.</param> public static void WriteGMVclass(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GMV gmv) { SB.AppendLine(""); WriteComment(SB, S, cgd, FT, gmv); string className = FT.GetMangledName(S, gmv.Name); SB.AppendLine("class " + className); SB.AppendLine("{"); WriteMemberVariables(SB, S, cgd, FT, gmv); SB.AppendLine("public:"); WriteFloatType(SB, S, cgd, FT, gmv, className); WriteConstructors(SB, S, cgd, FT, gmv, className); WriteAssignmentOperators(SB, S, cgd, FT, gmv, className); WriteSetDeclarations(SB, S, cgd, FT, gmv, className); WriteGetCoord(S, cgd, FT, SB); WriteSetCoord(S, cgd, FT, SB); WriteCompressExpandDeclarations(SB, S, cgd, FT, gmv, className); WriteLargestCoordinateDeclarations(SB, S, cgd, FT, gmv, className); // grade usage SB.AppendLine("\t/// returns grade/group."); SB.AppendLine("\tinline int gu() const {return m_gu;}"); WriteToString(SB, S, cgd, FT, gmv, className); // function which returns pointer to some array of zeros SB.AppendLine("public:"); SB.AppendLine("\tinline " + FT.type + " const *nullFloats() const {"); SB.AppendLine("\t\tstatic " + FT.type + " *nf = NULL;"); SB.AppendLine("\t\treturn (nf == NULL) ? (nf = new " + FT.type + "[" + S.m_GMV.NbCoordinates + "]) : nf;"); SB.AppendLine("\t}"); // function for setting grade/group usage, reallocting memory cgd.m_cog.EmitTemplate(SB, "GMVsetGroupUsage", "S=", S, "FT=", FT, "className=", className, "gmv=", gmv); // function for allocating a group cgd.m_cog.EmitTemplate(SB, "GMVallocateGroups", "S=", S, "FT=", FT, "className=", className, "gmv=", gmv); SB.AppendLine("}; // end of class " + className); }
/// <summary> /// Writes the definition of an GMV struct to 'SB' (including comments). /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="gmv">The general multivector for which the struct should be written.</param> public static void WriteGMVstruct(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GMV gmv) { SB.AppendLine(""); { // comments for type: SB.AppendLine("/**"); SB.AppendLine(" * This struct can hold a general multivector."); SB.AppendLine(" * "); SB.AppendLine(" * The coordinates are stored in type " + FT.type + "."); SB.AppendLine(" * "); SB.AppendLine(" * There are " + gmv.NbGroups + " coordinate groups:"); for (int g = 0; g < gmv.NbGroups; g++) { SB.Append(" * group " + g + ":"); for (int i = 0; i < gmv.Group(g).Length; i++) { if (i > 0) SB.Append(", "); SB.Append(gmv.Group(g)[i].ToString(S.m_basisVectorNames)); } if (gmv.Group(g).Length > 0) SB.Append(" (grade " + gmv.Group(g)[0].Grade() + ")"); SB.AppendLine("."); } SB.AppendLine(" * "); switch (S.m_GMV.MemoryAllocationMethod) { case G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE: SB.AppendLine(" * " + (gmv.NbCoordinates / 2) + " " + FT.type + "s are allocated inside the struct ('parity pure')."); SB.AppendLine(" * Hence creating a multivector which needs more than that number of coordinates "); SB.AppendLine(" * will result in unpredictable behaviour (buffer overflow)."); break; case G25.GMV.MEM_ALLOC_METHOD.FULL: SB.AppendLine(" * " + gmv.NbCoordinates + " " + FT.type + "s are allocated inside the struct."); break; } SB.AppendLine(" */"); } // end of comment // typedef SB.AppendLine("typedef struct "); SB.AppendLine("{"); // group/grade usage SB.AppendLine("\t/** group/grade usage (a bitmap which specifies which groups/grades are stored in 'c', below). */"); SB.AppendLine("\tint gu;"); // coordinates switch (S.m_GMV.MemoryAllocationMethod) { // case G25.GMV.MEM_ALLOC_METHOD.DYNAMIC: // SB.AppendLine("\t" + FT.type + " *c; ///< the coordinates (array is allocated using realloc())"); // break; case G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE: SB.AppendLine("\t/** The coordinates (note: parity pure). */"); SB.AppendLine("\t" + FT.type + " c[" + (gmv.NbCoordinates / 2) + "];"); break; case G25.GMV.MEM_ALLOC_METHOD.FULL: SB.AppendLine("\t/** The coordinates (full). */"); SB.AppendLine("\t" + FT.type + " c[" + (gmv.NbCoordinates) + "];"); break; } // If we report non-optimized function usage, we need to know original type of GMVs: if (S.m_reportUsage) { SB.AppendLine("\t/** Specialized multivector type. Used to report about non-optimized function usage. */"); SB.AppendLine("\tint t;"); } SB.AppendLine("} " + FT.GetMangledName(S, gmv.Name) + ";"); }
/// <summary> /// Generates a source file with the SMV class definition. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="smv"></param> /// <param name="FT"></param> /// <returns></returns> public static string GenerateCode(Specification S, G25.CG.Shared.CGdata cgd, G25.SMV smv, FloatType FT) { string className = FT.GetMangledName(S, smv.Name); // get filename, list of generated filenames List<string> generatedFiles = new List<string>(); string sourceFilename = MainGenerator.GetClassOutputPath(S, className); generatedFiles.Add(sourceFilename); // get StringBuilder where all generated code goes StringBuilder SB = new StringBuilder(); // get a new 'cgd' where all ouput goes to the one StringBuilder SB cgd = new G25.CG.Shared.CGdata(cgd, SB, SB, SB); // output license, copyright G25.CG.Shared.Util.WriteCopyright(SB, S); G25.CG.Shared.Util.WriteLicense(SB, S); // using ... Util.WriteGenericUsing(SB, S); // open namespace G25.CG.Shared.Util.WriteOpenNamespace(SB, S); // write class comment G25.CG.CSJ.SMV.WriteComment(SB, S, cgd, FT, smv); // open class string[] implements = new string[] { MvInterface.GetMvInterfaceName(S, FT) }; G25.CG.Shared.Util.WriteOpenClass(SB, S, G25.CG.Shared.AccessModifier.AM_public, className, null, implements); // member variables G25.CG.CSJ.SMV.WriteMemberVariables(SB, S, cgd, FT, smv); // indices into arrays G25.CG.CSJ.SMV.WriteSMVcoordIndices(SB, S, FT, smv); // special type to safeguard coordinates order in functions G25.CG.CSJ.SMV.WriteCoordinateOrder(SB, S, FT, smv); // write multivector interface implementation G25.CG.CSJ.SMV.WriteMultivectorInterface(SB, S, cgd, FT, smv); // write constructors G25.CG.CSJ.SMV.WriteConstructors(SB, S, cgd, FT, smv); // write set functions G25.CG.CSJ.SMV.WriteSetFunctions(SB, S, cgd, FT, smv); // write largest coordinate functions G25.CG.CSJ.SMV.WriteLargestCoordinateFunctions(S, cgd, FT, smv); // write 'ToString' functions G25.CG.CSJ.GMV.WriteToString(SB, S, cgd, FT, smv); // write get/set coords G25.CG.CSJ.SMV.WriteGetSetCoord(SB, S, cgd, FT, smv); // write shortcuts for functions G25.CG.Shared.Shortcut.WriteFunctionShortcuts(SB, S, cgd, FT, smv); // close class G25.CG.Shared.Util.WriteCloseClass(SB, S, className); // close namespace G25.CG.Shared.Util.WriteCloseNamespace(SB, S); // write all to file G25.CG.Shared.Util.WriteFile(sourceFilename, SB.ToString()); return sourceFilename; }
/// <summary> /// Writes any geometric product based product for general multivectors, /// based on gp parts code. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="declOnly"></param> /// <param name="productType"></param> /// <returns>name of generated function</returns> public static string WriteGMVgpFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.GPparts.ProductTypes productType) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.GPparts.GetGPcode(S, cgd, FT, M, productType, FAI, fgs.RETURN_ARG_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = null; G25.CG.Shared.FuncArgInfo returnArgument = null; if (productType == G25.CG.Shared.GPparts.ProductTypes.SCALAR_PRODUCT) { // return scalar returnTypeName = FT.type; } else { // return GMV (in C, via 'return argument') returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } string funcName = CF.OutputName; // FAI[0].MangledTypeName; //CF.ArgumentTypeNames[0] = CF.ArgumentTypeNames[0] + G25.CG.Shared.Main.IF_SUFFIX; // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return funcName; }