public void Serialize(object obj)
{
if (obj == null)
{
this.writer.Write((byte)ImageCode.Nil);
return;
}
if (obj is int)
{
this.writer.Write((byte)ImageCode.Integer);
this.writer.Write((int)obj);
return;
}
int position = this.objects.IndexOf(obj);
if (position >= 0)
{
this.writer.Write((byte)ImageCode.Reference);
this.writer.Write(position);
return;
}
if (obj is string)
{
this.writer.Write((byte)ImageCode.String);
this.writer.Write((string)obj);
return;
}
if (obj is Context)
{
var ctx = (Context)obj;
this.objects.Add(ctx);
this.writer.Write((byte)ImageCode.Context);
var names = ctx.GetNames();
int nnames = names.Count;
this.writer.Write(nnames);
foreach (var name in names)
{
this.writer.Write(name);
this.Serialize(ctx.GetValue(name));
}
return;
}
if (obj is NativeBehavior)
{
var nbehavior = (NativeBehavior)obj;
this.objects.Add(nbehavior);
this.writer.Write((byte)ImageCode.NativeBehavior);
this.Serialize(nbehavior.NativeType.FullName);
this.Serialize(nbehavior.SuperClass);
if (nbehavior.MetaClass.SuperClass is IClass)
this.Serialize(nbehavior.MetaClass.SuperClass);
else
this.Serialize(null);
var methods = nbehavior.GetInstanceMethods();
this.Serialize(methods.Count(mth => mth.SourceCode != null));
foreach (var method in methods)
if (method.SourceCode != null)
{
this.Serialize(method.Name);
this.Serialize(method.SourceCode);
}
var classmethods = nbehavior.GetClassMethods();
this.Serialize(classmethods.Count(mth => mth.SourceCode != null));
foreach (var method in classmethods)
if (method.SourceCode != null)
{
this.Serialize(method.Name);
this.Serialize(method.SourceCode);
}
return;
}
if (obj is IClass)
{
var klass = (IClass)obj;
this.objects.Add(klass);
this.writer.Write((byte)ImageCode.Class);
this.Serialize(klass.Name);
this.Serialize(klass.Category);
this.Serialize(klass.GetInstanceVariableNamesAsString());
this.Serialize(klass.GetClassVariableNamesAsString());
this.Serialize(klass.SuperClass);
if (klass.MetaClass.SuperClass is IClass)
this.Serialize(klass.MetaClass.SuperClass);
else
this.Serialize(null);
var methods = klass.GetInstanceMethods();
this.Serialize(methods.Count(mth => mth.SourceCode != null));
foreach (var method in methods)
if (method.SourceCode != null)
{
this.Serialize(method.Name);
this.Serialize(method.SourceCode);
}
var classmethods = klass.GetClassMethods();
this.Serialize(classmethods.Count(mth => mth.SourceCode != null));
foreach (var method in classmethods)
if (method.SourceCode != null)
{
this.Serialize(method.Name);
this.Serialize(method.SourceCode);
}
return;
}
if (obj is IObject)
{
var iobj = (IObject)obj;
this.objects.Add(iobj);
this.writer.Write((byte)ImageCode.Object);
this.Serialize(iobj.Behavior);
int nvars = iobj.NoVariables;
this.Serialize(nvars);
for (int k = 0; k < nvars; k++)
this.Serialize(iobj[k]);
return;
}
if (obj is Machine)
{
var mach = (Machine)obj;
this.objects.Add(mach);
this.objects.Add(mach.Environment);
this.writer.Write((byte)ImageCode.Machine);
var names = mach.GetGlobalNames().ToList();
int nnames = names.Count;
this.writer.Write(nnames);
foreach (var name in names)
{
this.writer.Write(name);
this.Serialize(mach.GetGlobalObject(name));
}
return;
}
throw new InvalidDataException();
}