public static void InitEnum(string[,] values, string insertAfter = null) { var e = new TpmEnum(values[0, 0], values[0, 1], values[0, 2]); for (int i = 1; i < values.GetLength(0); ++i) { e.Add(values[i, 0], values[i, 1], values[i, 2]); } Add(e, insertAfter); }
void GenUnions() { TpmUnion[] unions = TpmTypes.Get <TpmUnion>().ToArray(); foreach (TpmUnion t in unions) { string selectorType = t.Members[0].SelectorValue.EnclosingEnum.Name; WriteComment(t); Write("public interface " + t.Name); TabIn("{"); Write($"{selectorType} GetUnionSelector();"); TabOut("}"); } Write("public abstract partial class TpmStructureBase"); TabIn("{"); Write("Type UnionElementFromSelector(Type unionInterface, object selector)"); TabIn("{"); string elseClause = ""; foreach (TpmUnion t in unions) { Write($"{elseClause}if (unionInterface == typeof({t.Name}))"); TabIn("{"); TpmEnum selectorType = null; foreach (UnionMember m in t.Members) { if (selectorType == null) { selectorType = m.SelectorValue.EnclosingEnum; Write($"switch (({selectorType.Name})selector)"); TabIn("{"); } Debug.Assert(selectorType == m.SelectorValue.EnclosingEnum); Write($"case {m.SelectorValue.QualifiedName}: return typeof({m.Type.Name});"); } TabOut("}", false); // switch TabOut("}", false); // else if elseClause = "else "; } Write("else"); TabIn("{"); Write("throw new Exception(\"Unknown union interface type \" + unionInterface.Name);"); TabOut("}", false); // else Write("throw new Exception(\"Unknown selector value\" + selector + \" for \" + unionInterface.Name + \" union\");"); TabOut("}", false); // UnionElementFromSelector TabOut("}"); // TpmStructureBase } // GenUnions()
} // GenEnum() void GenEnum(TpmEnum e) { GenEnum(e, e.Members); }
/// <summary> Makes constant values specified as arithmetic expressions comply with the current /// langauge syntax (adds enum type name qualifiers and type casts when necessary, eliminates /// sizeof() operators when unsupported, etc.) </summary> public static string TranslateConstExpr(TpmConstExpr ce, TpmEnum enclosingEnum = null) { var nameDelimiters = new char[] { ' ', ',', '{', '}', '(', ')', '+', '-', '<', '*', '/', '`' }; string suffix = TargetLang.Java ? ".toInt()" : ""; string expr = ce.Expr; string[] tokens = expr.Split(nameDelimiters); bool sizeofOccurred = false, commentNeeded = false; foreach (string token in tokens) { if (token.Length == 0) { continue; } if (token == "sizeof") { Debug.Assert(!sizeofOccurred); sizeofOccurred = true; continue; } if (Expression.IsNumber(token)) { if (token == "00") { Debug.Assert(expr == token); expr = "0"; } Debug.Assert(!sizeofOccurred); continue; } TpmNamedConstant nc = TpmTypes.LookupConstant(token); if (enclosingEnum != null && nc?.EnclosingEnum == enclosingEnum) { // Members of the enum being processed do not need to be qualified Debug.Assert(token == nc.SpecName); expr = expr.Replace(token, nc.Name + suffix); continue; } if (!TpmTypes.ContainsConstant(token)) { // This must be a type name operand of sizeof() Debug.Assert(sizeofOccurred); sizeofOccurred = false; TpmType t = TpmTypes.Lookup(token); if (t is TpmStruct || TargetLang.IsOneOf(Lang.Java, Lang.JS, Lang.Py)) { string sizeofExpr = "sizeof(" + token + ")"; Debug.Assert(expr.Contains(sizeofExpr)); commentNeeded = TargetLang.Py; string origExpr = TargetLang.Py ? "" : $"/*{sizeofExpr}*/"; expr = expr.Replace(sizeofExpr, $"0x{t.GetSize():X}{origExpr}"); } else if (TargetLang.DotNet) { expr = expr.Replace(token, t.StripTypedefs().Name); } } else { nc = TpmTypes.LookupConstant(token); var translated = nc.QualifiedName + suffix; if (!TargetLang.IsGenerated(nc.EnclosingEnum)) { translated = nc.NumericValue.ToString(); if (!TargetLang.Py) { translated += "/*" + token + "*/"; } else { commentNeeded = true; } } expr = expr.Replace(token, translated); } } // foreach token if (TargetLang.DotNet && expr.Contains("<<")) { // Shift operator in .Net requires right operand of type 'int' and unsigned left one. int curPos = 0; expr = expr.Replace(" << ", "<<"); do { int pos = expr.IndexOf("<<", curPos); if (pos == -1) { break; } curPos = pos + 2 + 6; // Add sizes of "<<" and "(uint)" while (char.IsLetterOrDigit(expr[--pos]) || expr[pos] == '.') { continue; } expr = expr.Insert(pos + 1, "(uint)"); } while (true); expr = expr.Replace("<<", " << (int)"); } if (commentNeeded) { expr += $" # {ce.Expr}"; } return(expr); } // TranslateConstExpr()
} // GenEnum void GenEnum(TpmEnum e) { GenEnum(e, e.Members, e.UnderlyingType.GetSize()); }
} // GenEnum() void GenEnum(TpmEnum e) { GenEnum(e, e.Members, null == e.Members.FirstOrDefault(x => x.Name == "None")); }
static bool IsGenerated(TpmEnum e) { // In Java mutual order of definitions is not important return(Java || (GeneratedEnums != null && GeneratedEnums.Contains(e))); }