/// <summary> /// Returns string to access coordinates number 'coordIdx'. /// </summary> /// <param name="S"></param> /// <param name="smv"></param> /// <param name="coordIdx"></param> /// <returns></returns> public static string GetCoordAccessString(Specification S, G25.SMV smv, int coordIdx) { if (S.m_coordStorage == COORD_STORAGE.VARIABLES) { return "m_" + smv.GetCoordLangID(coordIdx, S); } else { return "m_c[" + coordIdx + "]"; } }
/// <summary> /// Writes a function to set an SMV class to specified coordinates, for all floating point types. /// </summary> /// <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> public static void WriteSetCoords(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv) { //if (smv.NbNonConstBasisBlade == 0) return; cgd.m_defSB.AppendLine(""); //string className = FT.GetMangledName(S, smv.Name); string funcName = GMV.GetSetFuncName(S); bool mustCast = false; System.Collections.ArrayList L = new System.Collections.ArrayList(); int NB_ARGS = 1 + smv.NbNonConstBasisBlade; string[] argTypename = new String[NB_ARGS]; string[] argName = new String[NB_ARGS]; argTypename[0] = G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM; argName[0] = "co"; for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); argTypename[i + 1] = FT.type; string coordStr = "_" + smv.GetCoordLangID(i, S, COORD_STORAGE.VARIABLES); argName[i + 1] = coordStr; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, 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, null, computeMultivectorValue); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = false; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue); }
/// <summary> /// Returns a symbolic name for the coordinate 'idx' of 'smv' which can be used in the /// output code. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="smv">The specialized multivector for which the coordinate indices should be written.</param> /// <param name="idx">The specialized multivector for which the coordinate indices should be written.</param> /// <param name="FT"></param> /// <returns>The symbol for the define for coordinate index 'idx' of 'smv'.</returns> public static string GetCoordIndexDefine(Specification S, FloatType FT, G25.SMV smv, int idx) { return smv.GetCoordLangID(idx, S, COORD_STORAGE.VARIABLES).ToUpper(); }
/// <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> public static void WriteMemberVariables(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { int nbTabs = 1; string accessModifier = Keywords.PackageProtectedAccessModifier(S); // individual coordinates or one array? if (S.m_coordStorage == COORD_STORAGE.VARIABLES) { for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { string comment = "The " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(comment).Write(SB, S, nbTabs); SB.AppendLine("\t" + accessModifier + " " + FT.type + " m_" + smv.GetCoordLangID(i, S) + ";"); } } else { if (smv.NbNonConstBasisBlade > 0) { // emit: float c[3]; // e1, e2, e3 string comment = " The coordinates (stored in an array)."; new G25.CG.Shared.Comment(comment).Write(SB, S, nbTabs); SB.Append("\t" + accessModifier + " " + FT.type + "[] m_c = new " + FT.type + "[" + smv.NbNonConstBasisBlade + "]; // "); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { if (i > 0) SB.Append(", "); SB.Append(smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames)); } SB.AppendLine(""); } } }
/// <summary> /// Returns an array of 'access strings' which are source code expressions that can be /// used to access the coordinates of <c>smv</c>. The entries in the array correspond to /// the non-const basis blades in <c>smv</c>. /// /// An example of access strings is <c>"A.e1"</c>, <c>"A.e2"</c>, <c>"A.e3"</c>, for a 3-D vector type. /// This could also be <c>"A.c[0]"</c>, <c>"A.c[1]"</c>, <c>"A.c[2]"</c> if coordinates are stored in an array. /// /// If 'ptr' is true, <c>"->"</c> will be used to access instance variables, otherwise <c>"."</c> is used. /// (this may need to be tweaked as more languages are available for output). /// </summary> /// <param name="S">Used for basis blade names, language, COORD_STORAGE, etc.</param> /// <param name="smv">The specialized multivector for which access strings are generated.</param> /// <param name="smvName">The variable name to be used in the access strings. For example, specify <c>"A"</c> to get <c>"A.c[0]"</c> and so on.</param> /// <param name="ptr">Is the variable a pointer or a reference/value?</param> /// <returns>Array of strings that can be used to access the non-constant coordinates of the 'smv'.</returns> public static string[] GetAccessStr(Specification S, G25.SMV smv, string smvName, bool ptr) { string[] AL = new string[smv.NbNonConstBasisBlade]; string accessStr = (ptr) ? "->" : "."; string memberPrefix = ""; // C++: override "this->" to "" if (S.OutputCpp()) { memberPrefix = "m_"; if ((smvName == SmvUtil.THIS) && (ptr == true)) { smvName = ""; accessStr = ""; } } // C#, Java: override "this." to "" else if (S.OutputCSharpOrJava()) { memberPrefix = "m_"; if ((smvName == SmvUtil.THIS) && (ptr == false)) { smvName = ""; accessStr = ""; } } string prefix = smvName + accessStr + memberPrefix; for (int i = 0; i < smv.NbNonConstBasisBlade; i++) AL[i] = prefix + smv.GetCoordLangID(i, S); return AL; }
/// <summary> /// Writes the definition of an SMV 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">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 WriteSMVstruct(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { SB.AppendLine(""); { // comments for type: SB.AppendLine("/**"); SB.AppendLine(" * This struct 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, 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(" */"); } // typedef SB.AppendLine("typedef struct "); SB.AppendLine("{"); // individual coordinates or one array? if (smv.NbNonConstBasisBlade > 0) { if (S.m_coordStorage == COORD_STORAGE.VARIABLES) { // emit float e1; float e2; float e3; for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine("\t/** The " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate. */"); SB.AppendLine("\t" + FT.type + " " + smv.GetCoordLangID(i, S) + ";"); //G25.CG.Shared.Util.BasisBladeToLangString(smv.NonConstBasisBlade(i), S.m_basisVectorNames) + ";"); } } else { // emit: float c[3]; // e1, e2, e3 SB.AppendLine("\t/** The coordinates (stored in an array). */"); SB.Append("\t" + FT.type + " c[" + smv.NbNonConstBasisBlade + "]; /* "); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { if (i > 0) SB.Append(", "); SB.Append(smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames)); } SB.AppendLine("*/"); } } else { SB.AppendLine("\t/** Filler, because C does not allow empty structs. */"); SB.AppendLine("\tint filler;"); } // emit: // no=1 for (int i = 0; i < smv.NbConstBasisBlade; i++) { SB.AppendLine("\t/* " + smv.ConstBasisBlade(i).ToString(S.m_basisVectorNames) + " = " + smv.ConstBasisBladeValue(i).ToString() + "*/"); } SB.AppendLine("} " + FT.GetMangledName(S, smv.Name) + ";"); }
/// <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> public static void WriteMemberVariables(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { SB.AppendLine("public:"); // individual coordinates or one array? if (S.m_coordStorage == COORD_STORAGE.VARIABLES) { for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine("\t/// The " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate."); SB.AppendLine("\t" + FT.type + " m_" + smv.GetCoordLangID(i, S) + ";"); } } else { if (smv.NbNonConstBasisBlade > 0) { // emit: float c[3]; // e1, e2, e3 SB.AppendLine("\t/// The coordinates (stored in an array)."); SB.Append("\t" + FT.type + " m_c[" + smv.NbNonConstBasisBlade + "]; // "); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { if (i > 0) SB.Append(", "); SB.Append(smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames)); } SB.AppendLine(""); } } }
/// <summary> /// Returns the comment for a SMV class. /// </summary> /// <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 Comment GetSmvComment(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv, bool emitCoordIndices) { StringBuilder SB = new StringBuilder(); 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: " + smv.GetCoordLangID(i, S, COORD_STORAGE.VARIABLES).ToUpper() + " = " + 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); } return new Comment(SB.ToString()); }