//TODO: Добавление уровня - неправильный путь борьбы с рекурсивными типами, но пока ... //TODO: А еще я похоже "напортачил" с вариантом (растущих) последовательностей ... public object ToPObject(int level) { if (level < 0) { return(null); } switch (this.vid) { case PTypeEnumeration.fstring: { return(new object[] { PType.ToInt(this.vid), ((PTypeFString)this).Size }); } case PTypeEnumeration.record: { PTypeRecord ptr = (PTypeRecord)this; var query = ptr.Fields.Select(pair => new object[] { pair.Name, pair.Type.ToPObject(level - 1) }).ToArray(); return(new object[] { PType.ToInt(this.vid), query }); } case PTypeEnumeration.sequence: { PTypeSequence pts = (PTypeSequence)this; return(new object[] { PType.ToInt(this.vid), new object[] { new object[] { "growing", new object[] { PType.ToInt(PTypeEnumeration.boolean), null } }, new object[] { "Type", pts.ElementType.ToPObject(level - 1) } } }); } case PTypeEnumeration.union: { PTypeUnion ptu = (PTypeUnion)this; var query = ptu.Variants.Select(pair => new object[] { pair.Name, pair.Type.ToPObject(level - 1) }).ToArray(); return(new object[] { PType.ToInt(this.vid), query }); } default: return(new object[] { PType.ToInt(this.vid), null }); } }
public string Interpret(object v, bool withfieldnames = false) { switch (this.vid) { case PTypeEnumeration.none: return(""); case PTypeEnumeration.boolean: return(((bool)v).ToString()); case PTypeEnumeration.character: return("'" + ((char)v).ToString() + "'"); // Нужно учесть специальные символы case PTypeEnumeration.integer: return(((int)v).ToString()); case PTypeEnumeration.longinteger: return(((long)v).ToString()); case PTypeEnumeration.real: return(((double)v).ToString("G", CultureInfo.InvariantCulture)); case PTypeEnumeration.fstring: return("\"" + ((string)v).Replace("\"", "\\\"") + "\""); case PTypeEnumeration.sstring: return("\"" + ((string)v).Replace("\"", "\\\"") + "\""); case PTypeEnumeration.record: { PTypeRecord ptr = (PTypeRecord)this; object[] arr = (object[])v; StringBuilder sb = new StringBuilder(); sb.Append('{'); for (int i = 0; i < ptr.Fields.Length; i++) { if (i > 0) { sb.Append(','); } if (withfieldnames) { sb.Append(ptr.Fields[i].Name); sb.Append(':'); } sb.Append(ptr.Fields[i].Type.Interpret(arr[i])); } sb.Append('}'); return(sb.ToString()); } case PTypeEnumeration.sequence: { PTypeSequence pts = (PTypeSequence)this; PType tel = pts.ElementType; object[] arr = (object[])v; StringBuilder sb = new StringBuilder(); sb.Append('['); for (int i = 0; i < arr.Length; i++) { if (i > 0) { sb.Append(','); } sb.Append(tel.Interpret(arr[i])); } sb.Append(']'); return(sb.ToString()); } case PTypeEnumeration.union: { PTypeUnion ptu = (PTypeUnion)this; object[] arr = (object[])v; if (arr.Length != 2) { throw new Exception("incorrect data for union"); } int tag = (int)arr[0]; if (tag < 0 || tag >= ptu.Variants.Length) { throw new Exception("incorrect data for union"); } NamedType nt = ptu.Variants[tag]; return(nt.Name + "^" + nt.Type.Interpret(arr[1])); } case PTypeEnumeration.@byte: return(((byte)v).ToString()); // не реализован вариант объектной парыЫ default: throw new Exception("Can't interpret value by type"); } }