int CountCellsImpl(object obj, HashSet<object> visited)
{
if (obj == null) {
return 0;
} else if (obj is Value) {
var sv = (Value)obj;
switch (sv.Kind) {
case Value.Kinds.Null:
return 1;
case Value.Kinds.Integer:
return 1;
case Value.Kinds.String:
return sv.stringValue.Length + 1;
case Value.Kinds.Double:
return 1;
case Value.Kinds.Bool:
return 1;
case Value.Kinds.Array:
return 1 + CountCellsSvList (sv.arrayValue, visited);
case Value.Kinds.Hash:
return 1 + CountCellsHash (sv.hashValue, visited);
case Value.Kinds.Callable:
return 1 + CountCellsCallable (sv.CallableValue, visited);
case Value.Kinds.ReturnAddress:
return 1 + CountCellsReturnAddress (sv.ReturnAddressValue, visited);
case Value.Kinds.NamedBlock:
return 1 + CountCellsNamedBlock (sv.NamedBlockValue, visited);
case Value.Kinds.Struct:
return 1 + CountCellsStringArray (sv.StructValue.Fields, visited);
case Value.Kinds.StructInstance:
return 1 + CountCellsSvArray (sv.structInstanceValue.Values, visited);
default:
Utils.Panic ();
return 0;
}
} else if (visited.Contains (obj)) {
return 0;
} else if (obj is Value[]) {
return CountCellsSvArray ((Value[])obj, visited);
} else if (obj is List<Value>) {
return CountCellsSvList ((List<Value>)obj, visited);
} else if (obj is VmEnvironment) {
return CountCellsEnvironment ((VmEnvironment)obj, visited);
} else if (obj is VmEnvFrame) {
return CountCellsEnvFrame ((VmEnvFrame)obj, visited);
} else if (obj is string[]) {
return CountCellsStringArray ((string[])obj, visited);
} else {
Utils.Panic ();
return 0;
}
}