crosslang-libs/Tesses.CrossLang.BuildEssen.../src/crossvmfile.tcross

149 lines
5.3 KiB
Plaintext
Raw Normal View History

2024-12-30 11:56:46 +00:00
func Tesses.CrossLang.CrossVMFile()
{
return {
Info = "",
Name = "",
Version = "",
Dependencies = [],
Chunks = [],
Strings = [],
Functions = [],
Resources = [],
Sections = [],
Ensure = (this,strm,buff,len) =>{
if(strm.ReadBlock(buff,0,len) != len)
throw $"Could not read {len} byte(s)";
},
EnsureInt = (this,strm)=>{
var buff = ByteArray(4);
this.Ensure(strm,buff,4);
var number = 0;
number |= buff[0] << 24;
number |= buff[1] << 16;
number |= buff[2] << 8;
number |= buff[3];
return number;
},
EnsureString = (this,strm)=>{
var len = this.EnsureInt(strm);
var buff = ByteArray(len);
this.Ensure(strm, buff,len);
return buff.ToString();
},
GetString = (this,strm)=>{
var index = this.EnsureInt(strm);
if(index < this.Strings.Count) return this.Strings[index];
throw $"{index} is not less than {this.Strings.Count}";
},
Read = (this,stream)=>{
var header = ByteArray(8);
this.Ensure(stream, header, header.Count);
var hdrStr = header.ToString();
if(hdrStr != "TCROSSVM") throw "Invalid TCrossVM image.";
this.Ensure(stream, header, 5);
var version = Tesses.CrossLang.Version.FromBytes(header, 0);
if(version > Tesses.CrossLang.Version.Current) throw "Runtime is too old.";
this.Ensure(stream, header, 5);
this.Version = Tesses.CrossLang.Version.FromBytes(header,0);
var sec = ByteArray(4);
var sectionCount = this.EnsureInt(stream);
for(var i = 0; i < sectionCount; i++)
{
this.Ensure(stream, sec, sec.Count);
hdrStr = sec.ToString();
var tableLength = this.EnsureInt(stream);
if(hdrStr == "NAME")
{
this.Name = this.GetString(stream);
}
else if(hdrStr == "INFO")
{
this.Info = this.GetString(stream);
}
else if(hdrStr == "DEPS")
{
var _name = this.GetString(stream);
this.Ensure(stream, header, 5);
var _version = Tesses.CrossLang.Version.FromBytes(header,0);
this.Dependencies.Add({
Name = _name,
Version = _version
});
}
else if(hdrStr == "RESO")
{
var resource = ByteArray(tableLength);
this.Ensure(stream,resource,resource.Count);
this.Resources.Add(resource);
}
else if(hdrStr == "CHKS")
{
var chunkCount = this.EnsureInt(stream);
for(var j = 0; j < chunkCount; j++)
{
var _args = [];
var _argCount = this.EnsureInt(stream);
for(var k = 0; k < _argCount; k++)
{
_args.Add(this.GetString(stream));
}
var _code = ByteArray(this.EnsureInt(stream));
this.Ensure(stream,_code,_code.Count);
var chunk = {
Arguments = _args,
Code = _code
};
this.Chunks.Add(chunk);
}
}
else if(hdrStr == "FUNS")
{
var funLen = this.EnsureInt(stream);
for(var j = 0; j < funLen; j++)
{
var fnPartsCount = this.EnsureInt(stream);
var documentation = "";
var fnParts = [];
for(var k = 0; k < fnPartsCount; k++)
{
if(k == 0) documentation = this.GetString(stream);
else fnParts.Add(this.GetString(stream));
}
var fnId = this.EnsureInt(stream);
this.Functions.Add({
Documentation=documentation,
FunctionNameParts = fnParts,
Closure = fnId
});
}
}
else if(hdrStr == "STRS")
{
var strcnt = this.EnsureInt(stream);
for(var j = 0; j < strcnt; j++)
{
this.Strings.Add(this.EnsureString(stream));
}
}
else {
var data = ByteArray(tableLength);
this.Ensure(stream,data,data.Count);
this.Sections.Add({
Name=hdrStr,
Data = data
});
}
}
}
};
}