public static bool Compile(Record r2, out string msg)
{
msg = null;
r = new Record();
string script = null;
int scptype = 0;
foreach (SubRecord sr2 in r2.SubRecords)
{
if (sr2.Name == "SCTX")
{
script = sr2.GetStrData();
}
if (sr2.Name == "SCHR")
{
byte[] tmp = sr2.GetReadonlyData();
scptype = TypeConverter.h2si(tmp[16], tmp[17], tmp[18], tmp[19]);
}
}
if (script == null)
{
msg = "Script had no SCTX record to compile";
return false;
}
locals.Clear();
localList.Clear();
edidRefs.Clear();
refcount = 0;
errors.Clear();
ts = new TokenStream(script, errors);
if (errors.Count > 0)
{
return OutputErrors(out msg);
}
Token[] smt = ts.PopNextStatement();
if (smt.Length != 2 || !smt[0].IsKeyword(Keywords.ScriptName) || smt[1].token == null)
{
return ReturnError("Expected 'ScriptName <edid>'", out msg);
}
var sr = new SubRecord();
sr.Name = "EDID";
sr.SetStrData(smt[1].utoken, true);
r.AddRecord(sr);
r.UpdateShortDescription();
schr = new SubRecord();
schr.Name = "SCHR";
r.AddRecord(schr);
scda = new SubRecord();
scda.Name = "SCDA";
r.AddRecord(scda);
sr = new SubRecord();
sr.Name = "SCTX";
sr.SetStrData(script, false);
r.AddRecord(sr);
bw = new BinaryWriter(new MemoryStream());
Emit(0x001d);
Emit(0x0000);
try
{
HandleVariables();
}
catch (Exception ex)
{
return ReturnError(ex.Message, out msg);
}
for (int i = 0; i < localList.Count; i++)
{
if (localList[i].type == VarType.Ref)
{
sr = new SubRecord();
sr.Name = "SCRV";
sr.SetData(TypeConverter.si2h(i + 1));
r.AddRecord(sr);
refcount++;
localList[i].refid = refcount;
}
}
while (ts.PeekNextStatement().Length > 0)
{
try
{
HandleBlock();
}
catch (Exception ex)
{
return ReturnError(ex.Message, out msg);
}
}
if (errors.Count > 0)
{
return OutputErrors(out msg);
}
var header = new byte[20];
TypeConverter.si2h(refcount, header, 4);
TypeConverter.i2h((uint)bw.BaseStream.Length, header, 8);
TypeConverter.si2h(localList.Count, header, 12);
TypeConverter.si2h(scptype, header, 16);
schr.SetData(header);
byte[] compileddata = ((MemoryStream)bw.BaseStream).GetBuffer();
if (compileddata.Length != bw.BaseStream.Length)
{
Array.Resize(ref compileddata, (int)bw.BaseStream.Length);
}
scda.SetData(compileddata);
r2.SubRecords.Clear();
r2.SubRecords.AddRange(r.SubRecords);
bw.Close();
return true;
}