Made sunBinary extendable

Now custom binary types are possible
This commit is contained in:
arookas 2016-02-07 16:19:23 -05:00
parent b7126c1334
commit 4d7c1da517
2 changed files with 191 additions and 101 deletions

View file

@ -6,17 +6,130 @@ using System.Text;
using arookas.IO.Binary; using arookas.IO.Binary;
namespace arookas { namespace arookas {
class sunBinary : IDisposable { public abstract class sunBinary {
public abstract uint Offset { get; }
public virtual void Open() {
// stub
}
public virtual void Close() {
// stub
}
// text
public abstract void Keep();
public abstract void Back();
public abstract void Goto(uint offset);
public virtual sunPoint OpenPoint() {
return new sunPoint(Offset);
}
public virtual void ClosePoint(sunPoint point) {
ClosePoint(point, Offset);
}
public abstract void ClosePoint(sunPoint point, uint offset);
public virtual void BeginText() {
// stub
}
public abstract void WriteINT(int value);
public abstract void WriteFLT(float value);
public abstract void WriteSTR(int index);
public abstract void WriteADR(uint value);
public abstract void WriteVAR(int display, int index);
public abstract void WriteNOP();
public abstract void WriteINC(int display, int index);
public abstract void WriteDEC(int display, int index);
public abstract void WriteADD();
public abstract void WriteSUB();
public abstract void WriteMUL();
public abstract void WriteDIV();
public abstract void WriteMOD();
public abstract void WriteASS(int display, int index);
public abstract void WriteEQ();
public abstract void WriteNE();
public abstract void WriteGT();
public abstract void WriteLT();
public abstract void WriteGE();
public abstract void WriteLE();
public abstract void WriteNEG();
public abstract void WriteNOT();
public abstract void WriteAND();
public abstract void WriteOR();
public abstract void WriteBAND();
public abstract void WriteBOR();
public abstract void WriteSHL();
public abstract void WriteSHR();
public abstract void WriteCALL(uint offset, int count);
public abstract void WriteFUNC(int index, int count);
public abstract void WriteMKFR(int count);
public abstract void WriteMKDS(int display);
public abstract void WriteRET();
public abstract void WriteRET0();
public abstract sunPoint WriteJNE();
public abstract void WriteJNE(sunPoint point);
public abstract sunPoint WriteJMP();
public abstract void WriteJMP(sunPoint point);
public abstract void WritePOP();
public abstract void WriteINT0();
public abstract void WriteINT1();
public abstract void WriteEND();
public virtual void EndText() {
// stub
}
public virtual void BeginData() {
// stub
}
public abstract void WriteData(string data);
public virtual void EndData() {
// stub
}
public virtual void BeginSymbol() {
// stub
}
internal void WriteSymbol(sunSymbol symbol) {
if (symbol == null) {
throw new ArgumentNullException("symbol");
}
WriteSymbol(symbol.Type, symbol.Name, symbol.Data);
}
public abstract void WriteSymbol(sunSymbolType type, string name, uint data);
public virtual void EndSymbol() {
// stub
}
}
public struct sunPoint { public struct sunPoint {
readonly uint mOffset;
public uint Offset {
get { return mOffset; }
}
public sunPoint(uint offset) {
mOffset = offset;
}
public static implicit operator sunPoint(uint offset) {
return new sunPoint(offset);
}
public static implicit operator uint(sunPoint point) {
return point.mOffset;
}
}
sealed class sunSpcBinary : sunBinary {
aBinaryWriter mWriter; aBinaryWriter mWriter;
sunBinarySection mText, mData, mDataString, mSymbol, mSymbolString; sunBinarySection mText, mData, mDataString, mSymbol, mSymbolString;
int mDataCount, mSymbolCount, mVarCount; int mDataCount, mSymbolCount, mVarCount;
public uint Offset { public override uint Offset {
get { return mText.Offset; } get { return mText.Offset; }
} }
public sunBinary(Stream output) { public sunSpcBinary(Stream output) {
mWriter = new aBinaryWriter(output, Endianness.Big, Encoding.GetEncoding(932)); mWriter = new aBinaryWriter(output, Endianness.Big, Encoding.GetEncoding(932));
mText = new sunBinarySection(); mText = new sunBinarySection();
mData = new sunBinarySection(); mData = new sunBinarySection();
@ -26,11 +139,14 @@ namespace arookas {
mWriter.PushAnchor(); mWriter.PushAnchor();
} }
// close public override void ClosePoint(sunPoint point, uint offset) {
public void Dispose() { Keep();
Close(); Goto(point.Offset);
mText.Writer.Write32(offset);
Back();
} }
public void Close() {
public override void Close() {
// header // header
mWriter.WriteString("SPCB"); mWriter.WriteString("SPCB");
mWriter.Write32(0x1C); mWriter.Write32(0x1C);
@ -49,30 +165,17 @@ namespace arookas {
} }
// text // text
public void Keep() { public override void Keep() {
mText.Writer.Keep(); mText.Writer.Keep();
} }
public void Back() { public override void Back() {
mText.Writer.Back(); mText.Writer.Back();
} }
public void Goto(uint offset) { public override void Goto(uint offset) {
mText.Writer.Goto(offset); mText.Writer.Goto(offset);
} }
public sunPoint OpenPoint() { public override void WriteINT(int value) {
return new sunPoint(Offset);
}
public void ClosePoint(sunPoint point) {
ClosePoint(point, Offset);
}
public void ClosePoint(sunPoint point, uint offset) {
Keep();
Goto(point.Offset);
mText.Writer.Write32(offset);
Back();
}
public void WriteINT(int value) {
switch (value) { // shortcut commands switch (value) { // shortcut commands
case 0: WriteINT0(); return; case 0: WriteINT0(); return;
case 1: WriteINT1(); return; case 1: WriteINT1(); return;
@ -83,28 +186,28 @@ namespace arookas {
mText.Writer.Write8(0x00); mText.Writer.Write8(0x00);
mText.Writer.WriteS32(value); mText.Writer.WriteS32(value);
} }
public void WriteFLT(float value) { public override void WriteFLT(float value) {
#if DEBUG #if DEBUG
TraceInstruction("flt {0}", value); TraceInstruction("flt {0}", value);
#endif #endif
mText.Writer.Write8(0x01); mText.Writer.Write8(0x01);
mText.Writer.WriteF32(value); mText.Writer.WriteF32(value);
} }
public void WriteSTR(int index) { public override void WriteSTR(int index) {
#if DEBUG #if DEBUG
TraceInstruction("str {0}", index); TraceInstruction("str {0}", index);
#endif #endif
mText.Writer.Write8(0x02); mText.Writer.Write8(0x02);
mText.Writer.WriteS32(index); mText.Writer.WriteS32(index);
} }
public void WriteADR(uint value) { public override void WriteADR(uint value) {
#if DEBUG #if DEBUG
TraceInstruction("adr ${0:X8}", value); TraceInstruction("adr ${0:X8}", value);
#endif #endif
mText.Writer.Write8(0x03); mText.Writer.Write8(0x03);
mText.Writer.Write32(value); mText.Writer.Write32(value);
} }
public void WriteVAR(int display, int index) { public override void WriteVAR(int display, int index) {
#if DEBUG #if DEBUG
TraceInstruction("var {0} {1}", display, index); TraceInstruction("var {0} {1}", display, index);
#endif #endif
@ -112,13 +215,13 @@ namespace arookas {
mText.Writer.WriteS32(display); mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index); mText.Writer.WriteS32(index);
} }
public void WriteNOP() { public override void WriteNOP() {
#if DEBUG #if DEBUG
TraceInstruction("nop"); TraceInstruction("nop");
#endif #endif
mText.Writer.Write8(0x05); mText.Writer.Write8(0x05);
} }
public void WriteINC(int display, int index) { public override void WriteINC(int display, int index) {
#if DEBUG #if DEBUG
TraceInstruction("inc {0} {1}", display, index); TraceInstruction("inc {0} {1}", display, index);
#endif #endif
@ -126,7 +229,7 @@ namespace arookas {
mText.Writer.WriteS32(display); mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index); mText.Writer.WriteS32(index);
} }
public void WriteDEC(int display, int index) { public override void WriteDEC(int display, int index) {
#if DEBUG #if DEBUG
TraceInstruction("dec {0} {1}", display, index); TraceInstruction("dec {0} {1}", display, index);
#endif #endif
@ -134,37 +237,37 @@ namespace arookas {
mText.Writer.WriteS32(display); mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index); mText.Writer.WriteS32(index);
} }
public void WriteADD() { public override void WriteADD() {
#if DEBUG #if DEBUG
TraceInstruction("add"); TraceInstruction("add");
#endif #endif
mText.Writer.Write8(0x08); mText.Writer.Write8(0x08);
} }
public void WriteSUB() { public override void WriteSUB() {
#if DEBUG #if DEBUG
TraceInstruction("sub"); TraceInstruction("sub");
#endif #endif
mText.Writer.Write8(0x09); mText.Writer.Write8(0x09);
} }
public void WriteMUL() { public override void WriteMUL() {
#if DEBUG #if DEBUG
TraceInstruction("mul"); TraceInstruction("mul");
#endif #endif
mText.Writer.Write8(0x0A); mText.Writer.Write8(0x0A);
} }
public void WriteDIV() { public override void WriteDIV() {
#if DEBUG #if DEBUG
TraceInstruction("div"); TraceInstruction("div");
#endif #endif
mText.Writer.Write8(0x0B); mText.Writer.Write8(0x0B);
} }
public void WriteMOD() { public override void WriteMOD() {
#if DEBUG #if DEBUG
TraceInstruction("mod"); TraceInstruction("mod");
#endif #endif
mText.Writer.Write8(0x0C); mText.Writer.Write8(0x0C);
} }
public void WriteASS(int display, int index) { public override void WriteASS(int display, int index) {
#if DEBUG #if DEBUG
TraceInstruction("ass {0} {1}", display, index); TraceInstruction("ass {0} {1}", display, index);
#endif #endif
@ -173,91 +276,91 @@ namespace arookas {
mText.Writer.WriteS32(display); mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index); mText.Writer.WriteS32(index);
} }
public void WriteEQ() { public override void WriteEQ() {
#if DEBUG #if DEBUG
TraceInstruction("eq"); TraceInstruction("eq");
#endif #endif
mText.Writer.Write8(0x0E); mText.Writer.Write8(0x0E);
} }
public void WriteNE() { public override void WriteNE() {
#if DEBUG #if DEBUG
TraceInstruction("ne"); TraceInstruction("ne");
#endif #endif
mText.Writer.Write8(0x0F); mText.Writer.Write8(0x0F);
} }
public void WriteGT() { public override void WriteGT() {
#if DEBUG #if DEBUG
TraceInstruction("gt"); TraceInstruction("gt");
#endif #endif
mText.Writer.Write8(0x10); mText.Writer.Write8(0x10);
} }
public void WriteLT() { public override void WriteLT() {
#if DEBUG #if DEBUG
TraceInstruction("lt"); TraceInstruction("lt");
#endif #endif
mText.Writer.Write8(0x11); mText.Writer.Write8(0x11);
} }
public void WriteGE() { public override void WriteGE() {
#if DEBUG #if DEBUG
TraceInstruction("ge"); TraceInstruction("ge");
#endif #endif
mText.Writer.Write8(0x12); mText.Writer.Write8(0x12);
} }
public void WriteLE() { public override void WriteLE() {
#if DEBUG #if DEBUG
TraceInstruction("le"); TraceInstruction("le");
#endif #endif
mText.Writer.Write8(0x13); mText.Writer.Write8(0x13);
} }
public void WriteNEG() { public override void WriteNEG() {
#if DEBUG #if DEBUG
TraceInstruction("neg"); TraceInstruction("neg");
#endif #endif
mText.Writer.Write8(0x14); mText.Writer.Write8(0x14);
} }
public void WriteNOT() { public override void WriteNOT() {
#if DEBUG #if DEBUG
TraceInstruction("not"); TraceInstruction("not");
#endif #endif
mText.Writer.Write8(0x15); mText.Writer.Write8(0x15);
} }
public void WriteAND() { public override void WriteAND() {
#if DEBUG #if DEBUG
TraceInstruction("and"); TraceInstruction("and");
#endif #endif
mText.Writer.Write8(0x16); mText.Writer.Write8(0x16);
} }
public void WriteOR() { public override void WriteOR() {
#if DEBUG #if DEBUG
TraceInstruction("or"); TraceInstruction("or");
#endif #endif
mText.Writer.Write8(0x17); mText.Writer.Write8(0x17);
} }
public void WriteBAND() { public override void WriteBAND() {
#if DEBUG #if DEBUG
TraceInstruction("band"); TraceInstruction("band");
#endif #endif
mText.Writer.Write8(0x18); mText.Writer.Write8(0x18);
} }
public void WriteBOR() { public override void WriteBOR() {
#if DEBUG #if DEBUG
TraceInstruction("bor"); TraceInstruction("bor");
#endif #endif
mText.Writer.Write8(0x19); mText.Writer.Write8(0x19);
} }
public void WriteSHL() { public override void WriteSHL() {
#if DEBUG #if DEBUG
TraceInstruction("shl"); TraceInstruction("shl");
#endif #endif
mText.Writer.Write8(0x1A); mText.Writer.Write8(0x1A);
} }
public void WriteSHR() { public override void WriteSHR() {
#if DEBUG #if DEBUG
TraceInstruction("shr"); TraceInstruction("shr");
#endif #endif
mText.Writer.Write8(0x1B); mText.Writer.Write8(0x1B);
} }
public void WriteCALL(uint offset, int count) { public override void WriteCALL(uint offset, int count) {
#if DEBUG #if DEBUG
TraceInstruction("call ${0:X8} {1}", offset, count); TraceInstruction("call ${0:X8} {1}", offset, count);
#endif #endif
@ -265,7 +368,7 @@ namespace arookas {
mText.Writer.Write32(offset); mText.Writer.Write32(offset);
mText.Writer.WriteS32(count); mText.Writer.WriteS32(count);
} }
public void WriteFUNC(int index, int count) { public override void WriteFUNC(int index, int count) {
#if DEBUG #if DEBUG
TraceInstruction("func {0} {1}", index, count); TraceInstruction("func {0} {1}", index, count);
#endif #endif
@ -273,33 +376,33 @@ namespace arookas {
mText.Writer.WriteS32(index); mText.Writer.WriteS32(index);
mText.Writer.WriteS32(count); mText.Writer.WriteS32(count);
} }
public void WriteMKFR(int count) { public override void WriteMKFR(int count) {
#if DEBUG #if DEBUG
TraceInstruction("mkfr {0}", count); TraceInstruction("mkfr {0}", count);
#endif #endif
mText.Writer.Write8(0x1E); mText.Writer.Write8(0x1E);
mText.Writer.WriteS32(count); mText.Writer.WriteS32(count);
} }
public void WriteMKDS(int display) { public override void WriteMKDS(int display) {
#if DEBUG #if DEBUG
TraceInstruction("mkds {0}", display); TraceInstruction("mkds {0}", display);
#endif #endif
mText.Writer.Write8(0x1F); mText.Writer.Write8(0x1F);
mText.Writer.WriteS32(display); mText.Writer.WriteS32(display);
} }
public void WriteRET() { public override void WriteRET() {
#if DEBUG #if DEBUG
TraceInstruction("ret"); TraceInstruction("ret");
#endif #endif
mText.Writer.Write8(0x20); mText.Writer.Write8(0x20);
} }
public void WriteRET0() { public override void WriteRET0() {
#if DEBUG #if DEBUG
TraceInstruction("ret0"); TraceInstruction("ret0");
#endif #endif
mText.Writer.Write8(0x21); mText.Writer.Write8(0x21);
} }
public sunPoint WriteJNE() { public override sunPoint WriteJNE() {
#if DEBUG #if DEBUG
TraceInstruction("jne # UNFINISHED"); TraceInstruction("jne # UNFINISHED");
#endif #endif
@ -308,14 +411,14 @@ namespace arookas {
mText.Writer.Write32(0); // dummy mText.Writer.Write32(0); // dummy
return point; return point;
} }
public void WriteJNE(sunPoint point) { public override void WriteJNE(sunPoint point) {
#if DEBUG #if DEBUG
TraceInstruction("jne {0:X8}", point.Offset); TraceInstruction("jne {0:X8}", point.Offset);
#endif #endif
mText.Writer.Write8(0x22); mText.Writer.Write8(0x22);
mText.Writer.Write32(point.Offset); mText.Writer.Write32(point.Offset);
} }
public sunPoint WriteJMP() { public override sunPoint WriteJMP() {
#if DEBUG #if DEBUG
TraceInstruction("jmp # UNFINISHED"); TraceInstruction("jmp # UNFINISHED");
#endif #endif
@ -324,32 +427,32 @@ namespace arookas {
mText.Writer.Write32(0); // dummy mText.Writer.Write32(0); // dummy
return point; return point;
} }
public void WriteJMP(sunPoint point) { public override void WriteJMP(sunPoint point) {
#if DEBUG #if DEBUG
TraceInstruction("jmp {0:X8}", point.Offset); TraceInstruction("jmp {0:X8}", point.Offset);
#endif #endif
mText.Writer.Write8(0x23); mText.Writer.Write8(0x23);
mText.Writer.Write32(point.Offset); mText.Writer.Write32(point.Offset);
} }
public void WritePOP() { public override void WritePOP() {
#if DEBUG #if DEBUG
TraceInstruction("pop"); TraceInstruction("pop");
#endif #endif
mText.Writer.Write8(0x24); mText.Writer.Write8(0x24);
} }
public void WriteINT0() { public override void WriteINT0() {
#if DEBUG #if DEBUG
TraceInstruction("int0"); TraceInstruction("int0");
#endif #endif
mText.Writer.Write8(0x25); mText.Writer.Write8(0x25);
} }
public void WriteINT1() { public override void WriteINT1() {
#if DEBUG #if DEBUG
TraceInstruction("int1"); TraceInstruction("int1");
#endif #endif
mText.Writer.Write8(0x26); mText.Writer.Write8(0x26);
} }
public void WriteEND() { public override void WriteEND() {
#if DEBUG #if DEBUG
TraceInstruction("end"); TraceInstruction("end");
#endif #endif
@ -364,7 +467,7 @@ namespace arookas {
#endif #endif
// data // data
public void WriteData(string data) { public override void WriteData(string data) {
if (data == null) { if (data == null) {
throw new ArgumentNullException("data"); throw new ArgumentNullException("data");
} }
@ -374,13 +477,7 @@ namespace arookas {
} }
// symbol // symbol
public void WriteSymbol(sunSymbol symbol) { public override void WriteSymbol(sunSymbolType type, string name, uint data) {
if (symbol == null) {
throw new ArgumentNullException("symbol");
}
WriteSymbol(symbol.Type, symbol.Name, symbol.Data);
}
public void WriteSymbol(sunSymbolType type, string name, uint data) {
mSymbol.Writer.WriteS32((int)type); mSymbol.Writer.WriteS32((int)type);
mSymbol.Writer.Write32(mSymbolString.Size); mSymbol.Writer.Write32(mSymbolString.Size);
mSymbol.Writer.Write32(data); mSymbol.Writer.Write32(data);
@ -428,22 +525,4 @@ namespace arookas {
} }
} }
} }
readonly uint mOffset;
public uint Offset {
get { return mOffset; }
}
public sunPoint(uint offset) {
mOffset = offset;
}
public static implicit operator sunPoint(uint offset) {
return new sunPoint(offset);
}
public static implicit operator uint(sunPoint point) {
return point.mOffset;
}
}
} }

View file

@ -29,11 +29,14 @@ namespace arookas {
return Compile(name, output, sunImportResolver.Default); return Compile(name, output, sunImportResolver.Default);
} }
public sunCompilerResults Compile(string name, Stream output, sunImportResolver resolver) { public sunCompilerResults Compile(string name, Stream output, sunImportResolver resolver) {
return Compile(name, new sunSpcBinary(output), resolver);
}
public sunCompilerResults Compile(string name, sunBinary binary, sunImportResolver resolver) {
if (name == null) { if (name == null) {
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
} }
if (output == null) { if (binary == null) {
throw new ArgumentNullException("output"); throw new ArgumentNullException("binary");
} }
if (resolver == null) { if (resolver == null) {
throw new ArgumentNullException("resolver"); throw new ArgumentNullException("resolver");
@ -41,18 +44,26 @@ namespace arookas {
var results = new sunCompilerResults(); var results = new sunCompilerResults();
var timer = Stopwatch.StartNew(); var timer = Stopwatch.StartNew();
try { try {
mBinary = binary;
mResolver = resolver; mResolver = resolver;
mContext.Clear(); mContext.Clear();
using (mBinary = new sunBinary(output)) { mBinary.Open();
CompileBody(name); mBinary.BeginText();
CompileFunctions(); CompileBody(name);
CompileFunctions();
#if SSC_CLEAN_SYMBOLS #if SSC_CLEAN_SYMBOLS
CleanSymbols(); CleanSymbols();
#endif #endif
CompileRelocations(); CompileRelocations();
CompileData(); mBinary.EndText();
CompileSymbols(); mBinary.BeginData();
} CompileData();
mBinary.EndData();
mBinary.BeginSymbol();
CompileSymbols();
mBinary.EndSymbol();
mBinary.Close();
results.DataCount = mContext.DataTable.Count; results.DataCount = mContext.DataTable.Count;
results.SymbolCount = mContext.SymbolTable.Count; results.SymbolCount = mContext.SymbolTable.Count;
results.BuiltinCount = mContext.SymbolTable.GetCount<sunBuiltinSymbol>(); results.BuiltinCount = mContext.SymbolTable.GetCount<sunBuiltinSymbol>();