using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Anonymus
{
public static class LibraryLoader
{
enum IdentifierType
{
GlobalVariable,
MemberVariable,
Function,
MemberFunction,
ConstructorFunction,
TupleType,
ValueType,
ClassType,
RefType,
PointerType,
TypeDefType,
EnumType,
FlagType,
FunctionType,
}
enum LibraryLoaderCommand
{
DeclareIds,
DeclareMembers,
Exit,
}
static Identifier GetIdByAsmName(BinaryReader Reader, List<Identifier> Ids)
{
var RAsmName = Reader.ReadString();
foreach (var e in Ids)
if (e.AsmName == RAsmName) return e;
return null;
}
static Identifier ReadIdentifier(BinaryReader Reader, List<Identifier> Ids, IdContainer Container)
{
var Ret = (Identifier)null;
var IdCode = Reader.ReadByte();
if (IdCode == 255) return GetIdByAsmName(Reader, Ids);
var IdType = (IdentifierType)IdCode;
var Name = new PString(Reader.ReadString());
var AsmName = Reader.ReadString();
var IsStatic = Reader.ReadBoolean();
var IsSealed = Reader.ReadBoolean();
//-----------------------------------------------------------------------------------
if (IdType == IdentifierType.GlobalVariable)
{
var Type = ReadIdentifier(Reader, Ids, Container) as Type;
if (Type == null) return null;
var V = new GlobalVariable(Container, Name, Type);
V.ReadOnly = Reader.ReadBoolean();
Ret = V;
}
else if (IdType == IdentifierType.MemberVariable)
{
var Type = ReadIdentifier(Reader, Ids, Container) as Type;
if (Type == null) return null;
var V = new MemberVariable(Container, Name, Type);
V.ReadOnly = Reader.ReadBoolean();
V.Offset = Reader.ReadInt32();
Ret = V;
}
//-----------------------------------------------------------------------------------
else if (IdType == IdentifierType.Function || IdType == IdentifierType.ConstructorFunction)
{
var FType = ReadIdentifier(Reader, Ids, Container) as FunctionType;
if (FType == null) return null;
if (IdType == IdentifierType.Function)
Ret = new Function(Container, Name, FType, null);
else if (IdType == IdentifierType.ConstructorFunction)
Ret = new ConstructorFunction(Container, Name, FType, null);
else throw new Exception("ERROR");
}
//-----------------------------------------------------------------------------------
else if (IdType == IdentifierType.MemberFunction)
{
var FType = ReadIdentifier(Reader, Ids, Container) as FunctionType;
if (FType == null) return null;
var MRet = new MemberFunction(Container, Name, FType, null);
MRet.Offset = Reader.ReadInt32();
Ret = MRet;
}
//-----------------------------------------------------------------------------------
else if (IdType == IdentifierType.RefType || IdType == IdentifierType.PointerType ||
IdType == IdentifierType.TypeDefType)
{
var ChType = ReadIdentifier(Reader, Ids, Container) as Type;
if (ChType == null) return null;
if (IdType == IdentifierType.RefType)
return ChType.CreateRefType(Container, Name);
else if (IdType == IdentifierType.PointerType)
return ChType.CreatePointerType(Container, Name);
else if (IdType == IdentifierType.TypeDefType)
return new TypeDefType(Container, Name, ChType);
else throw new Exception("ERROR");
}
//-----------------------------------------------------------------------------------
else if (IdType == IdentifierType.TupleType || IdType == IdentifierType.ClassType ||
IdType == IdentifierType.ValueType)
{
var Members = ReadIdList(Reader, Ids, Container);
var SRet = (StructuredType)null;
if (IdType == IdentifierType.TupleType)
SRet = new TupleType(Container, Name);
else if (IdType == IdentifierType.ValueType)
SRet = new ValueType(Container, Name);
else if (IdType == IdentifierType.ValueType)
SRet = new ClassType(Container, Name);
else throw new Exception("ERROR");
SRet.Members = Members;
Ret = SRet;
}
//-----------------------------------------------------------------------------------
else if (IdType == IdentifierType.FunctionType)
{
var Conv = (CallConv)Reader.ReadByte();
var RetType = ReadIdentifier(Reader, Ids, Container) as Type;
if (RetType == null) return null;
var ParamCount = Reader.ReadUInt16();
var Params = new VarDeclList();
for (var i = 0; i < ParamCount; i++)
{
var Type = ReadIdentifier(Reader, Ids, Container) as Type;
if (Type == null) return null;
var PName = new PString(Reader.ReadString());
var Decl = new VarDecl(null, null, Type, PName, null);
Params.Add(Decl);
}
Ret = new FunctionType(Container, Name, Conv, RetType, Params);
}
//-----------------------------------------------------------------------------------
else
{
throw new Exception("ERROR");
}
if (Ret == null) throw new Exception("ERROR");
Ret.AsmName = AsmName;
Ret.IsStatic = IsStatic;
Ret.IsSealed = IsSealed;
Ids.Add(Ret);
return Ret;
}
static IdentifierList ReadIdList(BinaryReader Reader, List<Identifier> Ids, IdContainer Container)
{
var Ret = new IdentifierList();
var Count = Reader.ReadUInt16();
for (var i = 0; i < Count; i++)
{
var Id = ReadIdentifier(Reader, Ids, Container);
if (Id == null) return null;
Ret.Add(Id);
}
return Ret;
}
static bool LoadLibrary(Stream Stream, IdContainer Container)
{
var Reader = new BinaryReader(Stream);
var Format = Reader.ReadString();
if (Format != "AsLib") return false;
var Ids = new List<Identifier>();
while (true)
{
var Comm = (LibraryLoaderCommand)Reader.ReadByte();
if (Comm == LibraryLoaderCommand.DeclareIds)
{
var Res = ReadIdList(Reader, Ids, Container);
if (Res == null) return false;
Ids.AddRange(Res);
}
else if (Comm == LibraryLoaderCommand.DeclareMembers)
{
var Id = GetIdByAsmName(Reader, Ids) as StructuredType;
if (Id == null) return false;
var Res = ReadIdList(Reader, Ids, Container);
if (Res == null) return false;
if (Id.Members == null) Id.Members = new IdentifierList();
Id.Members.AddRange(Res);
}
else if (Comm == LibraryLoaderCommand.Exit)
{
break;
}
else
{
throw new Exception("ERROR");
}
}
Reader.Close();
return true;
}
static List<StructuredType> SaveIdentifier(BinaryWriter Writer, Identifier Id, bool Root = true)
{
var Type = Id as Type;
if (Type != null && Type.DeclaredType)
{
Writer.Write((byte)255);
Writer.Write(Id.AsmName);
return null;
}
var IdType = GetIdType(Id);
Writer.Write((byte)IdType);
Writer.Write(Id.Name.String);
Writer.Write(Id.AsmName);
Writer.Write(Id.IsStatic);
Writer.Write(Id.IsSealed);
//-----------------------------------------------------------------------------------
if (Id is Type)
{
if (Id is FunctionType)
{
var FType = Id as FunctionType;
Writer.Write((int)FType.Conv);
var Ret = SaveIdentifier(Writer, FType.RetType, false);
Writer.Write((ushort)FType.Params.Count);
foreach (var e in FType.Params)
{
if (Ret == null) Ret = SaveIdentifier(Writer, e.Type, false);
else Ret.AddRange(SaveIdentifier(Writer, e.Type, false));
Writer.Write(e.Name.String);
}
return Ret;
}
else if (Id is RefType || Id is PointerType || Id is TypeDefType)
{
var Ch = (Type)null;
if (Id is RefType) Ch = (Id as RefType).Child;
else if (Id is PointerType) Ch = (Id as PointerType).Child;
else if (Id is TypeDefType) Ch = (Id as TypeDefType).Child;
else throw new Exception("ERROR");
return SaveIdentifier(Writer, Ch, false);
}
else if (Id is ChildType)
{
return SaveIdentifier(Writer, (Id as ChildType).Child, false);
}
else
{
throw new Exception("ERROR");
}
}
//-----------------------------------------------------------------------------------
else if (Id is Variable)
{
var Var = Id as Variable;
SaveIdentifier(Writer, Var.Type, false);
Writer.Write(Var.ReadOnly);
if (Id is MemberVariable)
{
var MVar = Id as MemberVariable;
Writer.Write(MVar.Offset);
}
}
//-----------------------------------------------------------------------------------
else if (Id is Function)
{
var Func = Id as Function;
SaveIdentifier(Writer, Func.Type, false);
if (Id is MemberFunction)
{
var MFunc = Id as MemberFunction;
Writer.Write(MFunc.Offset);
}
}
//-----------------------------------------------------------------------------------
else
{
throw new Exception("ERROR");
}
return null;
}
static IdentifierType GetIdType(Identifier Id)
{
if (Id is GlobalVariable) return IdentifierType.GlobalVariable;
else if (Id is MemberVariable) return IdentifierType.MemberVariable;
else if (Id is Function) return IdentifierType.Function;
else if (Id is MemberFunction) return IdentifierType.MemberFunction;
else if (Id is ConstructorFunction) return IdentifierType.ConstructorFunction;
else if (Id is RefType) return IdentifierType.RefType;
else if (Id is PointerType) return IdentifierType.PointerType;
else if (Id is TypeDefType) return IdentifierType.TypeDefType;
else if (Id is TupleType) return IdentifierType.TupleType;
else if (Id is ValueType) return IdentifierType.ValueType;
else if (Id is ClassType) return IdentifierType.ClassType;
else if (Id is FunctionType) return IdentifierType.FunctionType;
else throw new Exception("ERROR");
}
static List<StructuredType> SaveTypes(BinaryWriter Writer, IdentifierList Ids)
{
var Count = 0;
foreach (var e in Ids)
if (e.DeclInThis && e is Type) Count++;
var Ret = new List<StructuredType>();
Writer.Write((ushort)Count);
foreach (var e in Ids)
if (e.DeclInThis && e is Type)
{
var Res = SaveIdentifier(Writer, e);
if (Res == null) continue;
foreach (var SType in Res)
{
Ret.Add(SType);
Ret.AddRange(SaveTypes(Writer, SType.Members));
}
}
return Ret;
}
public static void SaveNonTypes(BinaryWriter Writer, IdentifierList Ids)
{
var Count = 0;
foreach (var e in Ids)
if (e.DeclInThis && !(e is Type)) Count++;
Writer.Write((ushort)Count);
foreach (var e in Ids)
if (e.DeclInThis && !(e is Type))
{
SaveIdentifier(Writer, e);
}
}
public static void SaveLibrary(Stream Stream, IdContainer Container)
{
var Writer = new BinaryWriter(Stream);
Writer.Write("AsLib");
Writer.Write((byte)LibraryLoaderCommand.DeclareIds);
var Types = SaveTypes(Writer, Container.Identifiers);
Writer.Write((byte)LibraryLoaderCommand.DeclareIds);
SaveNonTypes(Writer, Container.Identifiers);
foreach (var e in Types)
{
Writer.Write((byte)LibraryLoaderCommand.DeclareMembers);
Writer.Write((byte)255);
Writer.Write(e.AsmName);
SaveNonTypes(Writer, e.Members);
}
Writer.Close();
}
public static bool LoadLibrary(string FileName, IdContainer Container)
{
var Strm = File.OpenRead(FileName);
if (Strm == null) return false;
var Ret = true;
try
{
Ret = LoadLibrary(Strm, Container);
}
catch (Exception e)
{
Ret = false;
}
Strm.Dispose();
return Ret;
}
public static bool SaveLibrary(string FileName, IdContainer Container)
{
var Strm = File.OpenWrite(FileName);
if (Strm == null) return false;
SaveLibrary(Strm, Container);
Strm.Dispose();
return true;
}
}
public class NewLibraryLoader
{
enum LibLoaderCommand
{
Typedef,
Class,
Struct,
Members,
Exit,
}
[Flags]
enum IdFlags
{
IsStatic = 1,
IsSealed = 2,
}
enum Types
{
ByAsmName,
Pointer,
Ref,
Tuple,
}
class LibLoaderType
{
}
public IdContainer Container;
public IdentifierList Ids;
public BinaryReader Reader;
public NewLibraryLoader(IdContainer Container)
{
this.Container = Container;
}
Identifier GetIdByAsmName(BinaryReader Reader)
{
var RAsmName = Reader.ReadString();
foreach (var e in Ids)
if (e.AsmName == RAsmName) return e;
return null;
}
Type ReadType()
{
var Type = (Types)Reader.ReadByte();
if (Type == Types.ByAsmName)
{
var AsmName = Reader.ReadString();
return GetIdByAsmName(Reader) as Type;
}
else if (Type == Types.Ref || Type == Types.Pointer)
{
var Ch = ReadType() as Type;
if (Ch == null) return null;
if (Type == Types.Pointer) return Ch.CreatePointerType();
else return Ch.CreateRefType();
}
else if (Type == Types.Tuple)
{
var Count = Reader.ReadByte();
var Members = new IdentifierList();
for (var i = 0; i < Count; i++)
{
var MemberType = ReadType();
var Name = new PString(Reader.ReadString());
var V = new MemberVariable(Container, Name, MemberType);
V.Offset = Reader.ReadInt32();
Members.Add(V);
}
return new TupleType(Container, Members, false);
}
return null;
}
public bool LoadLibrary(Stream Stream)
{
Reader = new BinaryReader(Stream);
Ids = new IdentifierList();
try
{
var Format = Reader.ReadString();
if (Format != "AsLib") throw new Exception("ERROR");
while (true)
{
var Comm = (LibLoaderCommand)Reader.ReadByte();
if (Comm == LibLoaderCommand.Typedef)
{
}
else if (Comm == LibLoaderCommand.Exit)
{
break;
}
}
}
catch (Exception)
{
Reader.Close();
return false;
}
Reader.Close();
Reader = null;
Ids = null;
return true;
}
public bool LoadLibrary(string FileName)
{
var Strm = File.OpenRead(FileName);
if (Strm == null) return false;
var Ret = LoadLibrary(Strm);
Strm.Dispose();
return Ret;
}
public bool SaveLibrary(string FileName, IdContainer Container)
{
var Strm = File.OpenWrite(FileName);
if (Strm == null) return false;
//SaveLibrary(Strm, Container);
Strm.Dispose();
return true;
}
}
}