public static void ParseFunction(Specification S, XmlElement E) { // storage for all info: String functionName = null; String outputFunctionName = null; const int MAX_NB_ARGS = 100; String returnTypeName = ""; String[] argumentTypeNames = new String[MAX_NB_ARGS]; String[] argumentVariableName = new String[MAX_NB_ARGS]; List<String> floatNames = new List<string>(); String metricName = "default"; String comment = ""; int nbArgs = 0; Dictionary<String, String> options = new Dictionary<string, string>(); { // handle attributes XmlAttributeCollection A = E.Attributes; // handle all attributes for (int i = 0; i < A.Count; i++) { // functionName if (A[i].Name == XML_NAME) functionName = A[i].Value; // functionName else if (A[i].Name == XML_OUTPUT_NAME) outputFunctionName = A[i].Value; // metricName else if (A[i].Name == XML_METRIC) metricName = A[i].Value.ToLower(); // comment else if (A[i].Name == XML_COMMENT) comment = A[i].Value; // floatType else if (A[i].Name == XML_FLOAT_TYPE) floatNames.Add(A[i].Value); // return type else if (A[i].Name == XML_RETURN_TYPE) { returnTypeName = A[i].Value; if (!S.IsTypeName(returnTypeName)) { if (returnTypeName.ToLower() == XML_SCALAR) // "scalar" is also allowed as returntype { returnTypeName = XML_SCALAR; } else throw new G25.UserException("Error parsing function '" + functionName + "': '" + returnTypeName + "' is not a type (inside element '" + XML_FUNCTION + "')."); } } // argNameX else if (A[i].Name.StartsWith(XML_ARGNAME)) { int argNameIdx = 0; try { argNameIdx = System.Int32.Parse(A[i].Name.Substring(XML_ARGNAME.Length)) - 1; } catch (System.Exception) { throw new G25.UserException("Error parsing function '" + functionName + "': invalid attribute '" + A[i].Name + "' in element '" + XML_FUNCTION + "'."); } if ((argNameIdx >= argumentVariableName.Length) || (argNameIdx < 0)) throw new G25.UserException("Error parsing function '" + functionName + "': invalid attribute index '" + A[i].Name + "' in element '" + XML_FUNCTION + "'."); argumentVariableName[argNameIdx] = A[i].Value; } // argX else if (A[i].Name.StartsWith(XML_ARG)) { int argIdx = 0; try { argIdx = System.Int32.Parse(A[i].Name.Substring(XML_ARG.Length)) - 1; } catch (System.Exception) { throw new G25.UserException("Error parsing function '" + functionName + "': invalid attribute '" + A[i].Name + "' in element '" + XML_FUNCTION + "'."); } if ((argIdx >= argumentTypeNames.Length) || (argIdx < 0)) throw new G25.UserException("Error parsing function '" + functionName + "': invalid attribute index '" + A[i].Name + "' in element '" + XML_FUNCTION + "'."); string typeName = A[i].Value; if (!S.IsTypeName(typeName)) { // it may be a constant, like 'e1', try adding a "_t" if (S.IsTypeName(typeName + Specification.CONSTANT_TYPE_SUFFIX)) { typeName = typeName + Specification.CONSTANT_TYPE_SUFFIX; } else throw new G25.UserException("Error parsing function '" + functionName + "': '" + typeName + "' is not a type (inside element '" + XML_FUNCTION + "')"); } argumentTypeNames[argIdx] = typeName; if (argIdx >= nbArgs) nbArgs = argIdx + 1; } else if (A[i].Name.StartsWith(XML_OPTION)) { String optionName = A[i].Name.Substring(XML_OPTION.Length).ToLower(); if (optionName.Length > 0) { String optionValue = A[i].Value; options[optionName] = optionValue; } } } // check if function name was specified: if (functionName == null) throw new G25.UserException("Missing attribute '" + XML_NAME + "' in element '" + XML_FUNCTION + "'"); // if output function name is missing, just use the regular function name if (outputFunctionName == null) outputFunctionName = functionName; // if no float type are specified, copy all from specification if (floatNames.Count == 0) { foreach (FloatType FT in S.m_floatTypes) floatNames.Add(FT.type); } // resize arguments arrays: Array.Resize(ref argumentTypeNames, nbArgs); Array.Resize(ref argumentVariableName, nbArgs); // check for nulls in argument arrays for (int i = 0; i < argumentTypeNames.Length; i++) { if (argumentTypeNames[i] == null) throw new G25.UserException("XML parsing error in function '" + functionName + "': Missing attribute '" + XML_ARG + (1 + i).ToString() + "' in element '" + XML_FUNCTION + "'"); if (argumentVariableName[i] == null) argumentVariableName[i] = fgs.DefaultArgumentName(i); } } fgs F = new fgs(functionName, outputFunctionName, returnTypeName, argumentTypeNames, argumentVariableName, floatNames.ToArray(), metricName, comment, options); S.m_functions.Add(F); }
/// <summary> /// Parses an XML_SMV element and stores the result. /// /// The XML_SMV element should contain the name, and optionally the type, const property and constant name. /// /// If the const property is true and no name is specified, the regular name is used as the name /// of the singleton constant and the name of the type is renamed to name_t. /// /// </summary> /// <param name="E">XML_SMV element</param> private static void ParseSMVelementAndAttributes(Specification S, XmlElement E) { string typeName = null; bool isConstant = false; string constantName = null; SMV.MULTIVECTOR_TYPE mvType = SMV.MULTIVECTOR_TYPE.MULTIVECTOR; { // handle attributes XmlAttributeCollection A = E.Attributes; // handle all attributes for (int i = 0; i < A.Count; i++) { // name if (A[i].Name == XML_NAME) typeName = A[i].Value; // const else if (A[i].Name == XML_CONST) isConstant = (A[i].Value.ToLower() == XML_TRUE); // type else if (A[i].Name == XML_TYPE) { if (A[i].Value == XML_MULTIVECTOR) mvType = SMV.MULTIVECTOR_TYPE.MULTIVECTOR; else if (A[i].Value == XML_BLADE) mvType = SMV.MULTIVECTOR_TYPE.BLADE; else if (A[i].Value == XML_ROTOR) mvType = SMV.MULTIVECTOR_TYPE.ROTOR; else if (A[i].Value == XML_VERSOR) mvType = SMV.MULTIVECTOR_TYPE.VERSOR; else throw new G25.UserException("XML parsing error: Invalid value for attribute'" + XML_TYPE + "':'" + A[i].Value + "' in element '" + XML_SMV + "'."); } } // sanity check on name if (typeName == null) throw new G25.UserException("XML parsing error: Missing '" + XML_NAME + "' attribute in element '" + XML_SMV + "'."); // if constant and no constantName provided, use the typeName as the constantName, and set typeName to typeName + "_t" if (isConstant && (constantName == null)) { // if a constant should be generated and no constant name is specified constantName = typeName; typeName = constantName + Specification.CONSTANT_TYPE_SUFFIX; } // check if name is already present if (S.IsTypeName(typeName)) throw new G25.UserException("In specialized multivector definition: type '" + typeName + "' already exists."); } // end of 'handle attributes' // parse list of basis blades and optional comment List<G25.rsbbp.BasisBlade> L = ParseBasisBladeList(S, E.FirstChild, typeName); string comment = ParseComment(S, E.FirstChild); if (L == null) throw new G25.UserException("XML parsing error in element '" + XML_SMV + "': Missing basis blade list for specialized multivector '" + typeName + "'"); SMV smv = new SMV(typeName, L.ToArray(), mvType, comment); // add new type to list of specialized multivectors S.AddSpecializedMV(smv); // if constant name is specified, the user wants a constant: if (constantName != null) S.AddConstant(new ConstantSMV(constantName, smv, null, comment)); }
private static void ParseSOMelementAndAttributes(Specification S, XmlElement E) { bool specialized = true; SOM som = ParseOMelementAndAttributes(S, E, specialized) as SOM; if (S.IsTypeName(som.Name)) throw new G25.UserException("In specialized outermorphism definition: a type '" + som.Name + "' already exists."); S.AddSpecializedOM(som); }
private static void ParseGOMelementAndAttributes(Specification S, XmlElement E) { bool specialized = false; GOM gom = ParseOMelementAndAttributes(S, E, specialized) as GOM; if (S.IsTypeName(gom.Name)) throw new G25.UserException("In general outermorphism definition: a type '" + gom.Name + "' already exists."); S.SetGeneralOM(gom); }