private string describe(object item)
{
byte[] b;
List<object> list;
Function fnc;
if ((b = item as byte[]) != null)
return "Byte array: “{0}” ({1})".Fmt(b.FromUtf8().CLiteralEscape(), ScliptingUtil.ToInt(b));
else if (item is BigInteger)
return "Integer: {0}".Fmt(item);
else if (item is string)
return "String: “{0}”".Fmt(((string) item).CLiteralEscape());
else if (item is double)
return "Float: {0}".Fmt(ExactConvert.ToString((double) item));
else if (item is Mark)
return "Mark";
else if ((list = item as List<object>) != null)
return "List ({0} items)".Fmt(list.Count) + list.Select((itm, idx) => Environment.NewLine + describe(itm, idx)).JoinString().Indent(4, false);
else if ((fnc = item as Function) != null)
return "Function" + (fnc.CapturedItem != null ? "; capture: " + describe(fnc.CapturedItem) : "; no capture");
// unknown type of object?
return "{0} ({1})".Fmt(item, item.GetType().FullName);
}