Exemplo n.º 1
0
Arquivo: xml.cs Projeto: Sciumo/gaigen
        /// <summary>
        /// Converts this specification to XML (that can be parsed by the constructor)
        /// </summary>
        /// <returns>An XML string that can be parsed by the constructor</returns>
        public static string ToXmlString(Specification S)
        {
            StringBuilder SB = new StringBuilder();
            SB.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
            SB.AppendLine(""); // empty line
            SB.Append("<" + XML_G25_SPEC + "\n");

            bool customLicense = false; // used later on to know whether to emit full license text
            { // output attributes of g25spec element
                { // license
                    string licString = S.m_license;
                    if (licString == Licenses.GPL_LICENSE)
                        licString = XML_GPL;
                    else if (licString == Licenses.BSD_LICENSE)
                        licString = XML_BSD;
                    else
                    {
                        licString = XML_CUSTOM;
                        customLicense = true;
                    }
                    SB.Append("\t" + XML_LICENSE + "=\"" + licString + "\"\n");
                }

                { // copyright
                    if ((S.m_copyright != null) && (S.m_copyright.Length > 0))
                        SB.Append("\t" + XML_COPYRIGHT + "=\"" + S.m_copyright + "\"\n");
                }

                { // language
                    SB.Append("\t" + XML_LANGUAGE + "=\"" + S.GetOutputLanguageString() + "\"\n");
                }

                // namespace
                if ((S.m_namespace != null) && (S.m_namespace.Length > 0))
                    SB.Append("\t" + XML_NAMESPACE + "=\"" + S.m_namespace + "\"\n");

                // coordinate storage
                SB.Append("\t" + XML_COORD_STORAGE + "=\"" + ((S.m_coordStorage == COORD_STORAGE.ARRAY) ? XML_ARRAY : XML_VARIABLES) + "\"\n");

                // operator bindings
                SB.Append("\t" + XML_DEFAULT_OPERATOR_BINDINGS + "=\"" + (S.DefaultOperatorBindings() ? XML_TRUE : XML_FALSE) + "\"\n");

                // dimension
                SB.Append("\t" + XML_DIMENSION + "=\"" + S.m_dimension.ToString() + "\"\n");

                // report usage of non-optimized functions
                SB.Append("\t" + XML_REPORT_USAGE + "=\"" + (S.m_reportUsage ? XML_TRUE : XML_FALSE) + "\"\n");

                { // what type of GMV code to generate:
                    SB.Append("\t" + XML_GMV_CODE + "=\"");
                    switch (S.m_gmvCodeGeneration)
                    {
                        case GMV_CODE.EXPAND: SB.Append(XML_EXPAND); break;
                        case GMV_CODE.RUNTIME: SB.Append(XML_RUNTIME); break;
                        default: SB.Append("BAD GMV CODE OPTION"); break;
                    }
                    SB.Append("\"\n");
                }

                { // what type of parser to generate:
                    SB.Append("\t" + XML_PARSER + "=\"");
                    switch (S.m_parserType)
                    {
                        case PARSER.NONE: SB.Append(XML_NONE); break;
                        case PARSER.ANTLR: SB.Append(XML_ANTLR); break;
                        case PARSER.BUILTIN: SB.Append(XML_BUILTIN); break;
                        default: SB.Append("BAD PARSER OPTION"); break;
                    }
                    SB.Append("\"\n");
                }

                // generate test suite
                SB.Append("\t" + XML_TEST_SUITE + "=\"" + (S.m_generateTestSuite ? XML_TRUE : XML_FALSE) + "\"\n");

            }

            SB.Append("\t>\n"); // end of <g25spec> entry

            SB.AppendLine(""); // empty line

            if (customLicense) // output custom license
                SB.Append("<" + XML_CUSTOM_LICENSE + ">" + S.m_license + "</" + XML_CUSTOM_LICENSE + ">\n");

            if (S.m_verbatimCode.Count > 0) // output verbatim code
            {
                foreach (VerbatimCode VC in S.m_verbatimCode)
                {
                    // determine if code is in XML or in file:
                    bool hasCode = ((VC.m_verbatimCode != null) && (VC.m_verbatimCode.Length > 0));
                    // open XML tag
                    SB.Append("<" + XML_VERBATIM);

                    // output all filenames to which verbatim code should be applied
                    for (int f = 0; f < VC.m_filenames.Count; f++)
                    {
                        SB.Append(" " + XML_FILENAME);
                        if (f > 0) SB.Append((f + 1).ToString());
                        SB.Append("=\"" + VC.m_filenames[f] + "\"");
                    }

                    // output the filename where verbatim code comes from
                    if ((VC.m_verbatimCodeFile != null) && (VC.m_verbatimCodeFile.Length > 0))
                        SB.Append(" " + XML_CODE_FILENAME + "=\"" + VC.m_verbatimCodeFile + "\"");

                    // output position
                    SB.Append(" " + XML_POSITION + "=");
                    switch (VC.m_where)
                    {
                        case VerbatimCode.POSITION.TOP:
                            SB.Append("\"" + XML_TOP + "\"");
                            break;
                        case VerbatimCode.POSITION.BOTTOM:
                            SB.Append("\"" + XML_BOTTOM + "\"");
                            break;
                        case VerbatimCode.POSITION.BEFORE_MARKER:
                            SB.Append("\"" + XML_BEFORE_MARKER + "\"");
                            break;
                        case VerbatimCode.POSITION.AFTER_MARKER:
                            SB.Append("\"" + XML_AFTER_MARKER + "\"");
                            break;
                    }

                    if ((VC.m_where == VerbatimCode.POSITION.BEFORE_MARKER) ||
                        (VC.m_where == VerbatimCode.POSITION.AFTER_MARKER))
                    {
                        SB.Append(" " + XML_MARKER + "=\"" + VC.m_customMarker + "\"");
                    }

                    // output verbatim code that goes into XML, if present
                    if (hasCode)
                    {
                        SB.Append(">" + VC.m_verbatimCode + "</" + XML_VERBATIM + ">\n");
                    }
                    else SB.Append("/>\n");
                }
            }

            if (S.m_outputDirectoryExplicitlySet) // output dir
                SB.Append("<" + XML_OUTPUT_DIRECTORY + " " + XML_PATH + "=\"" + S.m_outputDirectory + "\"/>\n");

            { // overrides
                foreach (KeyValuePair<string, string> kvp in S.m_outputFilenameOverrides)
                {
                    SB.Append("<" + XML_OUTPUT_FILENAME + " " +
                        XML_DEFAULT_NAME + "=\"" + kvp.Key + "\" " +
                        XML_CUSTOM_NAME + "=\"" + kvp.Value +
                        "\"/>\n");
                }
            }

            SB.AppendLine(""); // empty line

            { // inline
                SB.Append("<" + XML_INLINE + "\n");
                SB.Append("\t" + XML_CONSTRUCTORS + "=\"" + ((S.m_inlineConstructors) ? XML_TRUE : XML_FALSE) + "\"\n");
                SB.Append("\t" + XML_SET + "=\"" + ((S.m_inlineSet) ? XML_TRUE : XML_FALSE) + "\"\n");
                SB.Append("\t" + XML_ASSIGN + "=\"" + ((S.m_inlineAssign) ? XML_TRUE : XML_FALSE) + "\"\n");
                SB.Append("\t" + XML_OPERATORS + "=\"" + ((S.m_inlineOperators) ? XML_TRUE : XML_FALSE) + "\"\n");
                SB.Append("\t" + XML_FUNCTIONS + "=\"" + ((S.m_inlineFunctions) ? XML_TRUE : XML_FALSE) + "\"\n");
                SB.Append("\t/>\n"); // end of <inline> entry
            }

            SB.AppendLine(""); // empty line

            { // float types
                foreach (FloatType FT in S.m_floatTypes)
                {
                    SB.Append("<" + XML_FLOAT_TYPE + " " + XML_TYPE + "=\"" + FT.type + "\"");
                    if (FT.prefix.Length > 0) SB.Append(" " + XML_PREFIX + "=\"" + FT.prefix + "\"");
                    if (FT.suffix.Length > 0) SB.Append(" " + XML_SUFFIX + "=\"" + FT.suffix + "\"");
                    SB.Append("/>\n"); // end of <floatType> entry
                }
            }

            SB.AppendLine(""); // empty line

            { // basis vector names
                SB.Append("<" + XML_BASIS_VECTOR_NAMES);
                for (int i = 0; i < S.m_basisVectorNames.Count; i++)
                    SB.Append("\n\t" + XML_NAME + (i + 1).ToString() + "=\"" + S.m_basisVectorNames[i] + "\"");
                SB.Append("\n\t/>\n"); // end of <basisVectorNames> entry
            }

            SB.AppendLine(""); // empty line

            { // metric
                // printed out in order of basisvectors
                foreach (Metric M in S.m_metric)
                {
                    if (M.m_name == Specification.INTERNAL_EUCLIDEAN_METRIC) continue; // do not emit auto-generated metric to XML
                    for (int v1 = 0; v1 < S.m_dimension; v1++)
                        for (int v2 = 0; v2 < S.m_dimension; v2++)
                            for (int i = 0; i < M.m_metricBasisVectorIdx1.Count; i++)
                                if ((v1 == M.m_metricBasisVectorIdx1[i]) && (v2 == M.m_metricBasisVectorIdx2[i]))
                                {
                                    SB.Append("<" + XML_METRIC + " " + XML_NAME + "=\"" + M.m_name + "\"");
                                    if (!M.m_round) // default = true, so only print when false
                                        SB.Append(" " + XML_ROUND + "=\"" + XML_FALSE + "\"");
                                    SB.Append(">");
                                    SB.Append(S.m_basisVectorNames[v1] + "." + S.m_basisVectorNames[v2] + "=" + M.m_metricValue[i]);
                                    SB.Append("</" + XML_METRIC + ">\n");
                                }
                }
            }

            SB.AppendLine(""); // empty line

            // operators
            foreach (Operator op in S.m_operators)
            {
                // first check if this isn't a 'default operator'
                if (S.m_defaultOperators.Contains(op)) continue;

                bool unary = (op.NbArguments == 1);
                string opStr = (unary) ? XML_UNARY_OPERATOR : XML_BINARY_OPERATOR;

                SB.Append("<" + opStr + " " + XML_SYMBOL + "=\"" + op.Symbol + "\" " + XML_FUNCTION + "=\"" + op.FunctionName + "\"");

                if (unary && (!op.IsPrefix))
                {
                    SB.Append(" " + XML_PREFIX + "=\"" + XML_FALSE + "\"");
                }

                SB.Append("/>\n");

            }

            SB.AppendLine(""); // empty line

            if (S.m_GMV != null) // general multivector:
            {
                SB.Append("<" + XML_MV);

                // name
                SB.Append(" " + XML_NAME + "=\"" + S.m_GMV.Name + "\"");

                // compression (by grade, group)
                bool compressedByGrade = S.m_GMV.IsGroupedByGrade(S.m_dimension);
                SB.Append(" " + XML_COMPRESS + "=\"");
                if (compressedByGrade) SB.Append(XML_BY_GRADE + "\"");
                else SB.Append(XML_BY_GROUP + "\"");

                // coordinate order
                bool defaultCoordinateOrder = (compressedByGrade && S.m_GMV.CompareBasisBladeOrder(rsbbp.ListToDoubleArray(S.m_basisBladeParser.GetDefaultBasisBlades())));
                SB.Append(" " + XML_COORDINATE_ORDER + "=\"");
                if (defaultCoordinateOrder) SB.Append(XML_DEFAULT + "\"");
                else SB.Append(XML_CUSTOM + "\"");

                // memory allocation method
                SB.Append(" " + XML_MEM_ALLOC + "=\"");
                if (S.m_GMV.MemoryAllocationMethod == GMV.MEM_ALLOC_METHOD.PARITY_PURE)
                    SB.Append(XML_PARITY_PURE + "\"");
                else if (S.m_GMV.MemoryAllocationMethod == GMV.MEM_ALLOC_METHOD.FULL)
                    SB.Append(XML_FULL + "\"");
                else SB.Append(XML_DYNAMIC + "\"");
                SB.Append(">\n");

                if (!defaultCoordinateOrder)
                { // emit coordinate order:
                    string[] bvNames = (string[])S.m_basisVectorNames.ToArray();
                    // loop over all groups:
                    for (int g = 0; g < S.m_GMV.NbGroups; g++)
                    {
                        SB.Append("<" + XML_GROUP + ">");
                        // loop over all basis blades of group
                        for (int i = 0; i < S.m_GMV.Group(g).Length; i++)
                        {
                            if (i > 0) SB.Append(" ");

                            string bbStr = BasisBladeToString(S.m_GMV.BasisBlade(g, i), bvNames);
                            SB.Append(bbStr);
                        }
                        SB.Append("</" + XML_GROUP + ">\n");
                    }
                }

                SB.Append("</" + XML_MV + ">\n");
            }

            SB.AppendLine(""); // empty line

            // specialized multivectors
            for (int i = 0; i < S.m_SMV.Count; i++)
            {
                SB.Append(SMVtoXmlString(S, S.m_SMV[i]));
            }

            SB.AppendLine(""); // empty line

            // constants
            for (int i = 0; i < S.m_constant.Count; i++)
            {
                // assume only SMV constants for now
                ConstantSMV C = S.m_constant[i] as ConstantSMV;
                if (C == null) continue;

                // check if type has name X+CONSTANT_TYPE_SUFFIX and is constant
                if ((C.Type.GetName().Equals(C.Name + Specification.CONSTANT_TYPE_SUFFIX)) && (C.Type as SMV).IsConstant()) continue;

                SB.Append(ConstantToXmlString(S, C));
            }

            SB.AppendLine(""); // empty line

            // outermorphisms
            {
                // i = -1 = m_GOM, the rest is m_SOM
                for (int i = -1; i < S.m_SOM.Count; i++)
                {
                    if (i == 0) SB.AppendLine(""); // empty line

                    OM om = (i == -1) ? S.m_GOM as OM : S.m_SOM[i] as OM;
                    if (om == null) continue;
                    string XMLtag = ((om is GOM) ? XML_OM : XML_SOM);

                    SB.Append("<" + XMLtag);

                    // name
                    SB.Append(" " + XML_NAME + "=\"" + om.Name + "\"");

                    // coordinate order:
                    bool rangeEqualsDomain = om.DomainAndRangeAreEqual();
                    bool defaultCoordOrder = rangeEqualsDomain && om.CompareDomainOrder(rsbbp.ListToDoubleArray(S.m_basisBladeParser.GetDefaultBasisBlades()));
                    SB.Append(" " + XML_COORDINATE_ORDER + "=\"" + ((defaultCoordOrder) ? XML_DEFAULT : XML_CUSTOM) + "\"");

                    // end of XMLtag
                    SB.Append(">\n");

                    if (!defaultCoordOrder)
                    {
                        string[] bvNames = (string[])S.m_basisVectorNames.ToArray();
                        for (int dr = 0; dr < 2; dr++)
                        {
                            string XML_DOMAIN_OR_RANGE = (dr == 0) ? XML_DOMAIN : XML_RANGE;
                            RefGA.BasisBlade[][] B = (dr == 0) ? om.Domain : om.Range;
                            if ((dr == 1) && rangeEqualsDomain) continue;

                            SB.Append("<" + XML_DOMAIN_OR_RANGE + ">");
                            bool first = true;
                            for (int g = 0; g < B.Length; g++)
                            {
                                for (int b = 0; b < B[g].Length; b++)
                                {
                                    if (!first) SB.Append(" ");

                                    String bbStr = BasisBladeToString(B[g][b], bvNames);
                                    SB.Append(bbStr);

                                    first = false;
                                }
                            }

                            SB.Append("</" + XML_DOMAIN_OR_RANGE + ">\n");

                        }
                        // output domain info

                        if (!rangeEqualsDomain)
                        {
                            // output range info
                        }
                    }

                    SB.Append("</" + XMLtag + ">\n");
                }
            }

            SB.AppendLine(""); // empty line

            // function generation specifications
            for (int i = 0; i < S.m_functions.Count; i++)
                SB.AppendLine(FunctionToXmlString(S, S.m_functions[i]));

            SB.AppendLine(""); // empty line

            SB.Append("</" + XML_G25_SPEC + ">\n");

            return SB.ToString();
        }