Compare commits
5 commits
Author | SHA1 | Date | |
---|---|---|---|
|
74fc59f232 | ||
|
c556939972 | ||
|
23aee05fb4 | ||
|
fbb0430325 | ||
|
2f6058d49f |
9 changed files with 160 additions and 329 deletions
|
@ -66,25 +66,6 @@ namespace arookas {
|
||||||
|
|
||||||
public int LocalCount {
|
public int LocalCount {
|
||||||
get {
|
get {
|
||||||
#if SSC_SCOPES
|
|
||||||
var locals = 0;
|
|
||||||
var maxChildLocals = 0;
|
|
||||||
foreach (var child in this) {
|
|
||||||
if (child is sunVariableDeclaration || child is sunVariableDefinition) {
|
|
||||||
++locals;
|
|
||||||
}
|
|
||||||
else if (child is sunCompoundStatement) {
|
|
||||||
locals += child.LocalCount; // HACK: compound statements aren't their own scope
|
|
||||||
}
|
|
||||||
else if (!(child is sunFunctionDefinition)) { // don't recurse into function bodies
|
|
||||||
var childLocals = child.LocalCount;
|
|
||||||
if (childLocals > maxChildLocals) {
|
|
||||||
maxChildLocals = childLocals;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return locals + maxChildLocals;
|
|
||||||
#else
|
|
||||||
var locals = 0;
|
var locals = 0;
|
||||||
foreach (var child in this) {
|
foreach (var child in this) {
|
||||||
if (child is sunVariableDeclaration || child is sunVariableDefinition) {
|
if (child is sunVariableDeclaration || child is sunVariableDefinition) {
|
||||||
|
@ -95,7 +76,6 @@ namespace arookas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return locals;
|
return locals;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,9 +99,6 @@ namespace arookas {
|
||||||
: base(location) { }
|
: base(location) { }
|
||||||
|
|
||||||
public override void Compile(sunCompiler compiler) {
|
public override void Compile(sunCompiler compiler) {
|
||||||
#if SSC_SCOPES
|
|
||||||
compiler.Context.Scopes.Push();
|
|
||||||
#endif
|
|
||||||
var loop = PushLoop(compiler.Context);
|
var loop = PushLoop(compiler.Context);
|
||||||
TryCompile(Declaration, compiler);
|
TryCompile(Declaration, compiler);
|
||||||
var bodyPrologue = compiler.Binary.Offset;
|
var bodyPrologue = compiler.Binary.Offset;
|
||||||
|
@ -114,9 +111,6 @@ namespace arookas {
|
||||||
bodyEpilogue.Relocate();
|
bodyEpilogue.Relocate();
|
||||||
loop.BreakPoint = compiler.Binary.Offset;
|
loop.BreakPoint = compiler.Binary.Offset;
|
||||||
compiler.Context.Loops.Pop(compiler);
|
compiler.Context.Loops.Pop(compiler);
|
||||||
#if SSC_SCOPES
|
|
||||||
compiler.Context.Scopes.Pop();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class sunForDeclaration : sunNode {
|
class sunForDeclaration : sunNode {
|
||||||
|
|
|
@ -7,16 +7,6 @@
|
||||||
class sunStatementBlock : sunNode {
|
class sunStatementBlock : sunNode {
|
||||||
public sunStatementBlock(sunSourceLocation location)
|
public sunStatementBlock(sunSourceLocation location)
|
||||||
: base(location) { }
|
: base(location) { }
|
||||||
|
|
||||||
public override void Compile(sunCompiler compiler) {
|
|
||||||
#if SSC_SCOPES
|
|
||||||
compiler.Context.Scopes.Push(compiler.Context.Scopes.Top.Type);
|
|
||||||
#endif
|
|
||||||
base.Compile(compiler);
|
|
||||||
#if SSC_SCOPES
|
|
||||||
compiler.Context.Scopes.Pop();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class sunImport : sunNode {
|
class sunImport : sunNode {
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
var symbol = compiler.Context.DeclareVariable(this);
|
var symbol = compiler.Context.DeclareVariable(this);
|
||||||
symbol.Modifiers = Modifiers;
|
symbol.Modifiers = Modifiers;
|
||||||
if ((Modifiers & sunSymbolModifiers.Constant) != 0) {
|
if ((Modifiers & sunSymbolModifiers.Constant) != 0) {
|
||||||
throw new sunInvalidModifierException(this[0]);
|
throw new sunConstantDeclarationException(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
341
ssc/binary.cs
341
ssc/binary.cs
|
@ -87,380 +87,319 @@ namespace arookas {
|
||||||
|
|
||||||
sealed class sunSpcBinary : sunBinary {
|
sealed class sunSpcBinary : sunBinary {
|
||||||
aBinaryWriter mWriter;
|
aBinaryWriter mWriter;
|
||||||
sunSpcBinarySection mText, mData, mDataString, mSymbol, mSymbolString;
|
sunSpcStringTable mStringTable;
|
||||||
|
uint mTextOffset, mDataOffset, mSymbolOffset;
|
||||||
int mDataCount, mSymbolCount, mVarCount;
|
int mDataCount, mSymbolCount, mVarCount;
|
||||||
|
|
||||||
public override uint Offset {
|
public override uint Offset {
|
||||||
get { return mText.Offset; }
|
get { return (uint)mWriter.Position; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sunSpcBinary(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 sunSpcBinarySection();
|
mStringTable = new sunSpcStringTable(Encoding.GetEncoding(932));
|
||||||
mData = new sunSpcBinarySection();
|
|
||||||
mDataString = new sunSpcBinarySection();
|
|
||||||
mSymbol = new sunSpcBinarySection();
|
|
||||||
mSymbolString = new sunSpcBinarySection();
|
|
||||||
mWriter.PushAnchor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Open() {
|
||||||
|
mWriter.PushAnchor();
|
||||||
|
WriteHeader();
|
||||||
|
}
|
||||||
public override void Close() {
|
public override void Close() {
|
||||||
// header
|
WriteHeader();
|
||||||
mWriter.WriteString("SPCB");
|
mWriter.PopAnchor();
|
||||||
mWriter.Write32(0x1C);
|
}
|
||||||
mWriter.Write32(0x1C + mText.Size);
|
|
||||||
|
void WriteHeader() {
|
||||||
|
mWriter.Goto(0);
|
||||||
|
mWriter.Write8(0x53); // 'S'
|
||||||
|
mWriter.Write8(0x50); // 'P'
|
||||||
|
mWriter.Write8(0x43); // 'C'
|
||||||
|
mWriter.Write8(0x42); // 'B'
|
||||||
|
mWriter.Write32(mTextOffset);
|
||||||
|
mWriter.Write32(mDataOffset);
|
||||||
mWriter.WriteS32(mDataCount);
|
mWriter.WriteS32(mDataCount);
|
||||||
mWriter.Write32(0x1C + mText.Size + mData.Size + mDataString.Size);
|
mWriter.Write32(mSymbolOffset);
|
||||||
mWriter.WriteS32(mSymbolCount);
|
mWriter.WriteS32(mSymbolCount);
|
||||||
mWriter.WriteS32(mVarCount);
|
mWriter.WriteS32(mVarCount);
|
||||||
|
|
||||||
// sections
|
|
||||||
mText.Copy(mWriter);
|
|
||||||
mData.Copy(mWriter);
|
|
||||||
mDataString.Copy(mWriter);
|
|
||||||
mSymbol.Copy(mWriter);
|
|
||||||
mSymbolString.Copy(mWriter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// text
|
// text
|
||||||
public override void Keep() {
|
public override void Keep() {
|
||||||
mText.Writer.Keep();
|
mWriter.Keep();
|
||||||
}
|
}
|
||||||
public override void Back() {
|
public override void Back() {
|
||||||
mText.Writer.Back();
|
mWriter.Back();
|
||||||
}
|
}
|
||||||
public override void Goto(uint offset) {
|
public override void Goto(uint offset) {
|
||||||
mText.Writer.Goto(offset);
|
mWriter.Goto(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void BeginText() {
|
||||||
|
mTextOffset = Offset;
|
||||||
|
mWriter.PushAnchor();
|
||||||
|
}
|
||||||
public override void WriteINT(int value) {
|
public override 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;
|
||||||
}
|
}
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("int {0} # ${0:X}", value);
|
TraceInstruction("int {0} # ${0:X}", value);
|
||||||
#endif
|
mWriter.Write8(0x00);
|
||||||
mText.Writer.Write8(0x00);
|
mWriter.WriteS32(value);
|
||||||
mText.Writer.WriteS32(value);
|
|
||||||
}
|
}
|
||||||
public override void WriteFLT(float value) {
|
public override void WriteFLT(float value) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("flt {0}", value);
|
TraceInstruction("flt {0}", value);
|
||||||
#endif
|
mWriter.Write8(0x01);
|
||||||
mText.Writer.Write8(0x01);
|
mWriter.WriteF32(value);
|
||||||
mText.Writer.WriteF32(value);
|
|
||||||
}
|
}
|
||||||
public override void WriteSTR(int index) {
|
public override void WriteSTR(int index) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("str {0}", index);
|
TraceInstruction("str {0}", index);
|
||||||
#endif
|
mWriter.Write8(0x02);
|
||||||
mText.Writer.Write8(0x02);
|
mWriter.WriteS32(index);
|
||||||
mText.Writer.WriteS32(index);
|
|
||||||
}
|
}
|
||||||
public override void WriteADR(uint value) {
|
public override void WriteADR(uint value) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("adr ${0:X8}", value);
|
TraceInstruction("adr ${0:X8}", value);
|
||||||
#endif
|
mWriter.Write8(0x03);
|
||||||
mText.Writer.Write8(0x03);
|
mWriter.Write32(value);
|
||||||
mText.Writer.Write32(value);
|
|
||||||
}
|
}
|
||||||
public override void WriteVAR(int display, int index) {
|
public override void WriteVAR(int display, int index) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("var {0} {1}", display, index);
|
TraceInstruction("var {0} {1}", display, index);
|
||||||
#endif
|
mWriter.Write8(0x04);
|
||||||
mText.Writer.Write8(0x04);
|
mWriter.WriteS32(display);
|
||||||
mText.Writer.WriteS32(display);
|
mWriter.WriteS32(index);
|
||||||
mText.Writer.WriteS32(index);
|
|
||||||
}
|
}
|
||||||
public override void WriteNOP() {
|
public override void WriteNOP() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("nop");
|
TraceInstruction("nop");
|
||||||
#endif
|
mWriter.Write8(0x05);
|
||||||
mText.Writer.Write8(0x05);
|
|
||||||
}
|
}
|
||||||
public override void WriteINC(int display, int index) {
|
public override void WriteINC(int display, int index) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("inc {0} {1}", display, index);
|
TraceInstruction("inc {0} {1}", display, index);
|
||||||
#endif
|
mWriter.Write8(0x06);
|
||||||
mText.Writer.Write8(0x06);
|
mWriter.WriteS32(display);
|
||||||
mText.Writer.WriteS32(display);
|
mWriter.WriteS32(index);
|
||||||
mText.Writer.WriteS32(index);
|
|
||||||
}
|
}
|
||||||
public override void WriteDEC(int display, int index) {
|
public override void WriteDEC(int display, int index) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("dec {0} {1}", display, index);
|
TraceInstruction("dec {0} {1}", display, index);
|
||||||
#endif
|
mWriter.Write8(0x07);
|
||||||
mText.Writer.Write8(0x07);
|
mWriter.WriteS32(display);
|
||||||
mText.Writer.WriteS32(display);
|
mWriter.WriteS32(index);
|
||||||
mText.Writer.WriteS32(index);
|
|
||||||
}
|
}
|
||||||
public override void WriteADD() {
|
public override void WriteADD() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("add");
|
TraceInstruction("add");
|
||||||
#endif
|
mWriter.Write8(0x08);
|
||||||
mText.Writer.Write8(0x08);
|
|
||||||
}
|
}
|
||||||
public override void WriteSUB() {
|
public override void WriteSUB() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("sub");
|
TraceInstruction("sub");
|
||||||
#endif
|
mWriter.Write8(0x09);
|
||||||
mText.Writer.Write8(0x09);
|
|
||||||
}
|
}
|
||||||
public override void WriteMUL() {
|
public override void WriteMUL() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("mul");
|
TraceInstruction("mul");
|
||||||
#endif
|
mWriter.Write8(0x0A);
|
||||||
mText.Writer.Write8(0x0A);
|
|
||||||
}
|
}
|
||||||
public override void WriteDIV() {
|
public override void WriteDIV() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("div");
|
TraceInstruction("div");
|
||||||
#endif
|
mWriter.Write8(0x0B);
|
||||||
mText.Writer.Write8(0x0B);
|
|
||||||
}
|
}
|
||||||
public override void WriteMOD() {
|
public override void WriteMOD() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("mod");
|
TraceInstruction("mod");
|
||||||
#endif
|
mWriter.Write8(0x0C);
|
||||||
mText.Writer.Write8(0x0C);
|
|
||||||
}
|
}
|
||||||
public override void WriteASS(int display, int index) {
|
public override void WriteASS(int display, int index) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("ass {0} {1}", display, index);
|
TraceInstruction("ass {0} {1}", display, index);
|
||||||
#endif
|
mWriter.Write8(0x0D);
|
||||||
mText.Writer.Write8(0x0D);
|
mWriter.Write8(0x04); // unused (skipped over by TSpcInterp)
|
||||||
mText.Writer.Write8(0x04); // unused (skipped over by TSpcInterp)
|
mWriter.WriteS32(display);
|
||||||
mText.Writer.WriteS32(display);
|
mWriter.WriteS32(index);
|
||||||
mText.Writer.WriteS32(index);
|
|
||||||
}
|
}
|
||||||
public override void WriteEQ() {
|
public override void WriteEQ() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("eq");
|
TraceInstruction("eq");
|
||||||
#endif
|
mWriter.Write8(0x0E);
|
||||||
mText.Writer.Write8(0x0E);
|
|
||||||
}
|
}
|
||||||
public override void WriteNE() {
|
public override void WriteNE() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("ne");
|
TraceInstruction("ne");
|
||||||
#endif
|
mWriter.Write8(0x0F);
|
||||||
mText.Writer.Write8(0x0F);
|
|
||||||
}
|
}
|
||||||
public override void WriteGT() {
|
public override void WriteGT() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("gt");
|
TraceInstruction("gt");
|
||||||
#endif
|
mWriter.Write8(0x10);
|
||||||
mText.Writer.Write8(0x10);
|
|
||||||
}
|
}
|
||||||
public override void WriteLT() {
|
public override void WriteLT() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("lt");
|
TraceInstruction("lt");
|
||||||
#endif
|
mWriter.Write8(0x11);
|
||||||
mText.Writer.Write8(0x11);
|
|
||||||
}
|
}
|
||||||
public override void WriteGE() {
|
public override void WriteGE() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("ge");
|
TraceInstruction("ge");
|
||||||
#endif
|
mWriter.Write8(0x12);
|
||||||
mText.Writer.Write8(0x12);
|
|
||||||
}
|
}
|
||||||
public override void WriteLE() {
|
public override void WriteLE() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("le");
|
TraceInstruction("le");
|
||||||
#endif
|
mWriter.Write8(0x13);
|
||||||
mText.Writer.Write8(0x13);
|
|
||||||
}
|
}
|
||||||
public override void WriteNEG() {
|
public override void WriteNEG() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("neg");
|
TraceInstruction("neg");
|
||||||
#endif
|
mWriter.Write8(0x14);
|
||||||
mText.Writer.Write8(0x14);
|
|
||||||
}
|
}
|
||||||
public override void WriteNOT() {
|
public override void WriteNOT() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("not");
|
TraceInstruction("not");
|
||||||
#endif
|
mWriter.Write8(0x15);
|
||||||
mText.Writer.Write8(0x15);
|
|
||||||
}
|
}
|
||||||
public override void WriteAND() {
|
public override void WriteAND() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("and");
|
TraceInstruction("and");
|
||||||
#endif
|
mWriter.Write8(0x16);
|
||||||
mText.Writer.Write8(0x16);
|
|
||||||
}
|
}
|
||||||
public override void WriteOR() {
|
public override void WriteOR() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("or");
|
TraceInstruction("or");
|
||||||
#endif
|
mWriter.Write8(0x17);
|
||||||
mText.Writer.Write8(0x17);
|
|
||||||
}
|
}
|
||||||
public override void WriteBAND() {
|
public override void WriteBAND() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("band");
|
TraceInstruction("band");
|
||||||
#endif
|
mWriter.Write8(0x18);
|
||||||
mText.Writer.Write8(0x18);
|
|
||||||
}
|
}
|
||||||
public override void WriteBOR() {
|
public override void WriteBOR() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("bor");
|
TraceInstruction("bor");
|
||||||
#endif
|
mWriter.Write8(0x19);
|
||||||
mText.Writer.Write8(0x19);
|
|
||||||
}
|
}
|
||||||
public override void WriteSHL() {
|
public override void WriteSHL() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("shl");
|
TraceInstruction("shl");
|
||||||
#endif
|
mWriter.Write8(0x1A);
|
||||||
mText.Writer.Write8(0x1A);
|
|
||||||
}
|
}
|
||||||
public override void WriteSHR() {
|
public override void WriteSHR() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("shr");
|
TraceInstruction("shr");
|
||||||
#endif
|
mWriter.Write8(0x1B);
|
||||||
mText.Writer.Write8(0x1B);
|
|
||||||
}
|
}
|
||||||
public override void WriteCALL(uint offset, int count) {
|
public override void WriteCALL(uint offset, int count) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("call ${0:X8} {1}", offset, count);
|
TraceInstruction("call ${0:X8} {1}", offset, count);
|
||||||
#endif
|
mWriter.Write8(0x1C);
|
||||||
mText.Writer.Write8(0x1C);
|
mWriter.Write32(offset);
|
||||||
mText.Writer.Write32(offset);
|
mWriter.WriteS32(count);
|
||||||
mText.Writer.WriteS32(count);
|
|
||||||
}
|
}
|
||||||
public override void WriteFUNC(int index, int count) {
|
public override void WriteFUNC(int index, int count) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("func {0} {1}", index, count);
|
TraceInstruction("func {0} {1}", index, count);
|
||||||
#endif
|
mWriter.Write8(0x1D);
|
||||||
mText.Writer.Write8(0x1D);
|
mWriter.WriteS32(index);
|
||||||
mText.Writer.WriteS32(index);
|
mWriter.WriteS32(count);
|
||||||
mText.Writer.WriteS32(count);
|
|
||||||
}
|
}
|
||||||
public override void WriteMKFR(int count) {
|
public override void WriteMKFR(int count) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("mkfr {0}", count);
|
TraceInstruction("mkfr {0}", count);
|
||||||
#endif
|
mWriter.Write8(0x1E);
|
||||||
mText.Writer.Write8(0x1E);
|
mWriter.WriteS32(count);
|
||||||
mText.Writer.WriteS32(count);
|
|
||||||
}
|
}
|
||||||
public override void WriteMKDS(int display) {
|
public override void WriteMKDS(int display) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("mkds {0}", display);
|
TraceInstruction("mkds {0}", display);
|
||||||
#endif
|
mWriter.Write8(0x1F);
|
||||||
mText.Writer.Write8(0x1F);
|
mWriter.WriteS32(display);
|
||||||
mText.Writer.WriteS32(display);
|
|
||||||
}
|
}
|
||||||
public override void WriteRET() {
|
public override void WriteRET() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("ret");
|
TraceInstruction("ret");
|
||||||
#endif
|
mWriter.Write8(0x20);
|
||||||
mText.Writer.Write8(0x20);
|
|
||||||
}
|
}
|
||||||
public override void WriteRET0() {
|
public override void WriteRET0() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("ret0");
|
TraceInstruction("ret0");
|
||||||
#endif
|
mWriter.Write8(0x21);
|
||||||
mText.Writer.Write8(0x21);
|
|
||||||
}
|
}
|
||||||
public override void WriteJNE(uint offset) {
|
public override void WriteJNE(uint offset) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("jne ${0:X8}", offset);
|
TraceInstruction("jne ${0:X8}", offset);
|
||||||
#endif
|
mWriter.Write8(0x22);
|
||||||
mText.Writer.Write8(0x22);
|
mWriter.Write32(offset);
|
||||||
mText.Writer.Write32(offset);
|
|
||||||
}
|
}
|
||||||
public override void WriteJMP(uint offset) {
|
public override void WriteJMP(uint offset) {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("jmp ${0:X8}", offset);
|
TraceInstruction("jmp ${0:X8}", offset);
|
||||||
#endif
|
mWriter.Write8(0x23);
|
||||||
mText.Writer.Write8(0x23);
|
mWriter.Write32(offset);
|
||||||
mText.Writer.Write32(offset);
|
|
||||||
}
|
}
|
||||||
public override void WritePOP() {
|
public override void WritePOP() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("pop");
|
TraceInstruction("pop");
|
||||||
#endif
|
mWriter.Write8(0x24);
|
||||||
mText.Writer.Write8(0x24);
|
|
||||||
}
|
}
|
||||||
public override void WriteINT0() {
|
public override void WriteINT0() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("int0");
|
TraceInstruction("int0");
|
||||||
#endif
|
mWriter.Write8(0x25);
|
||||||
mText.Writer.Write8(0x25);
|
|
||||||
}
|
}
|
||||||
public override void WriteINT1() {
|
public override void WriteINT1() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("int1");
|
TraceInstruction("int1");
|
||||||
#endif
|
mWriter.Write8(0x26);
|
||||||
mText.Writer.Write8(0x26);
|
|
||||||
}
|
}
|
||||||
public override void WriteEND() {
|
public override void WriteEND() {
|
||||||
#if DEBUG
|
|
||||||
TraceInstruction("end");
|
TraceInstruction("end");
|
||||||
#endif
|
mWriter.Write8(0x27);
|
||||||
mText.Writer.Write8(0x27);
|
}
|
||||||
|
public override void EndText() {
|
||||||
|
mWriter.PopAnchor();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
[Conditional("DEBUG")]
|
||||||
void TraceInstruction(string format, params object[] args) {
|
void TraceInstruction(string format, params object[] args) {
|
||||||
var instruction = String.Format(format, args);
|
var instruction = String.Format(format, args);
|
||||||
Debug.WriteLine("{0:X8} {1}", mText.Size, instruction);
|
Debug.WriteLine("{0:X8} {1}", mWriter.Position, instruction);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// data
|
// data
|
||||||
|
public override void BeginData() {
|
||||||
|
mDataCount = 0;
|
||||||
|
mDataOffset = Offset;
|
||||||
|
mWriter.PushAnchor();
|
||||||
|
mStringTable.Clear();
|
||||||
|
}
|
||||||
public override void WriteData(string data) {
|
public override void WriteData(string data) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
throw new ArgumentNullException("data");
|
throw new ArgumentNullException("data");
|
||||||
}
|
}
|
||||||
mData.Writer.Write32(mDataString.Size);
|
mWriter.Write32(mStringTable.Add(data));
|
||||||
mDataString.Writer.WriteString<aZSTR>(data);
|
|
||||||
++mDataCount;
|
++mDataCount;
|
||||||
}
|
}
|
||||||
|
public override void EndData() {
|
||||||
|
mWriter.WriteString(mStringTable.ToString());
|
||||||
|
mWriter.PopAnchor();
|
||||||
|
mStringTable.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
// symbol
|
// symbol
|
||||||
|
public override void BeginSymbol() {
|
||||||
|
mSymbolCount = 0;
|
||||||
|
mSymbolOffset = Offset;
|
||||||
|
mWriter.PushAnchor();
|
||||||
|
mStringTable.Clear();
|
||||||
|
}
|
||||||
public override void WriteSymbol(sunSymbolType type, string name, uint data) {
|
public override void WriteSymbol(sunSymbolType type, string name, uint data) {
|
||||||
mSymbol.Writer.WriteS32((int)type);
|
mWriter.WriteS32((int)type);
|
||||||
mSymbol.Writer.Write32(mSymbolString.Size);
|
mWriter.Write32(mStringTable.Add(name));
|
||||||
mSymbol.Writer.Write32(data);
|
mWriter.Write32(data);
|
||||||
mSymbol.Writer.Write32(0u); // runtime field (hash)
|
mWriter.Write32(0u); // runtime field (hash)
|
||||||
mSymbol.Writer.Write32(0u); // runtime field (funcptr)
|
mWriter.Write32(0u); // runtime field (funcptr)
|
||||||
mSymbolString.Writer.WriteString<aZSTR>(name);
|
|
||||||
++mSymbolCount;
|
++mSymbolCount;
|
||||||
if (type == sunSymbolType.Variable) {
|
if (type == sunSymbolType.Variable) {
|
||||||
++mVarCount;
|
++mVarCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public override void EndSymbol() {
|
||||||
|
mWriter.WriteString(mStringTable.ToString());
|
||||||
|
mWriter.PopAnchor();
|
||||||
|
mStringTable.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
class sunSpcBinarySection : IDisposable {
|
class sunSpcStringTable {
|
||||||
readonly aBinaryWriter mWriter;
|
StringBuilder mBuilder;
|
||||||
readonly MemoryStream mStream;
|
Encoding mEncoding;
|
||||||
|
uint mSize;
|
||||||
|
|
||||||
public aBinaryWriter Writer {
|
public sunSpcStringTable(Encoding encoding) {
|
||||||
get { return mWriter; }
|
mBuilder = new StringBuilder(1024);
|
||||||
}
|
mEncoding = encoding;
|
||||||
public MemoryStream Stream {
|
|
||||||
get { return mStream; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Offset {
|
public uint Add(string value) {
|
||||||
get { return (uint)mWriter.Position; }
|
var size = mSize;
|
||||||
|
mBuilder.Append(value);
|
||||||
|
mBuilder.Append('\0');
|
||||||
|
mSize += (uint)mEncoding.GetByteCount(value) + 1u; // + null terminator
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
public uint Size {
|
public override string ToString() {
|
||||||
get { return (uint)mWriter.Length; }
|
return mBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
public void Clear() {
|
||||||
public sunSpcBinarySection() {
|
mBuilder.Clear();
|
||||||
mStream = new MemoryStream(1024);
|
mSize = 0;
|
||||||
mWriter = new aBinaryWriter(mStream, Endianness.Big, Encoding.GetEncoding(932));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() {
|
|
||||||
mStream.Dispose();
|
|
||||||
}
|
|
||||||
public void Copy(aBinaryWriter writer) {
|
|
||||||
if (writer == null) {
|
|
||||||
throw new ArgumentNullException("writer");
|
|
||||||
}
|
|
||||||
writer.Write8s(mStream.GetBuffer(), (int)Size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,16 +97,15 @@ namespace arookas {
|
||||||
}
|
}
|
||||||
sunVariableSymbol DeclareVariable(sunIdentifier node, sunSymbolModifiers modifiers) {
|
sunVariableSymbol DeclareVariable(sunIdentifier node, sunSymbolModifiers modifiers) {
|
||||||
var local = (modifiers & sunSymbolModifiers.Local) != 0;
|
var local = (modifiers & sunSymbolModifiers.Local) != 0;
|
||||||
|
if (local && Scopes.Count > 1) {
|
||||||
|
throw new sunLocalFunctionVariableException(node);
|
||||||
|
}
|
||||||
var name = MangleSymbolName(node.Value, node.Location.ScriptId, false, local);
|
var name = MangleSymbolName(node.Value, node.Location.ScriptId, false, local);
|
||||||
var symbol = Scopes.DeclareVariable(name);
|
var symbol = Scopes.DeclareVariable(name);
|
||||||
if (symbol == null) {
|
if (symbol == null) {
|
||||||
throw new sunRedeclaredVariableException(node);
|
throw new sunRedeclaredVariableException(node);
|
||||||
}
|
}
|
||||||
#if SSC_SCOPES
|
|
||||||
if (Scopes.Top.Type == sunScopeType.Script) {
|
|
||||||
#else
|
|
||||||
if (Scopes.Count == 1) {
|
if (Scopes.Count == 1) {
|
||||||
#endif
|
|
||||||
SymbolTable.Add(symbol);
|
SymbolTable.Add(symbol);
|
||||||
}
|
}
|
||||||
return symbol;
|
return symbol;
|
||||||
|
|
|
@ -259,4 +259,20 @@ namespace arookas {
|
||||||
public sunInvalidModifierException(sunNode node)
|
public sunInvalidModifierException(sunNode node)
|
||||||
: base(node) { }
|
: base(node) { }
|
||||||
}
|
}
|
||||||
|
class sunConstantDeclarationException : sunNodeException<sunVariableDeclaration> {
|
||||||
|
public override string Message {
|
||||||
|
get { return "Constant variables must be assigned a value."; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sunConstantDeclarationException(sunVariableDeclaration node)
|
||||||
|
: base(node) { }
|
||||||
|
}
|
||||||
|
class sunLocalFunctionVariableException : sunNodeException<sunNode> {
|
||||||
|
public override string Message {
|
||||||
|
get { return "Only script-scope variables can be declared local."; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sunLocalFunctionVariableException(sunNode node)
|
||||||
|
: base(node) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
83
ssc/scope.cs
83
ssc/scope.cs
|
@ -5,25 +5,11 @@ using System.Linq;
|
||||||
namespace arookas {
|
namespace arookas {
|
||||||
class sunScopeStack : IEnumerable<sunScope> {
|
class sunScopeStack : IEnumerable<sunScope> {
|
||||||
List<sunScope> mStack;
|
List<sunScope> mStack;
|
||||||
#if SSC_SCOPES
|
|
||||||
int mLocals;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public int Count {
|
public int Count {
|
||||||
get { return mStack.Count; }
|
get { return mStack.Count; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SSC_SCOPES
|
|
||||||
public sunScope Root {
|
|
||||||
get { return this.FirstOrDefault(i => i.Type == Top.Type); }
|
|
||||||
}
|
|
||||||
public sunScope Script {
|
|
||||||
get { return this.FirstOrDefault(i => i.Type == sunScopeType.Script); }
|
|
||||||
}
|
|
||||||
public sunScope Function {
|
|
||||||
get { return this.FirstOrDefault(i => i.Type == sunScopeType.Function); }
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public sunScope Top {
|
public sunScope Top {
|
||||||
get { return this[Count - 1]; }
|
get { return this[Count - 1]; }
|
||||||
}
|
}
|
||||||
|
@ -34,78 +20,32 @@ namespace arookas {
|
||||||
|
|
||||||
public sunScopeStack() {
|
public sunScopeStack() {
|
||||||
mStack = new List<sunScope>(8);
|
mStack = new List<sunScope>(8);
|
||||||
#if SSC_SCOPES
|
|
||||||
Push(sunScopeType.Script); // push global scope
|
|
||||||
#else
|
|
||||||
Push();
|
Push();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Push() {
|
public void Push() {
|
||||||
#if SSC_SCOPES
|
|
||||||
Push(Top.Type);
|
|
||||||
#else
|
|
||||||
mStack.Add(new sunScope());
|
mStack.Add(new sunScope());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if SSC_SCOPES
|
|
||||||
public void Push(sunScopeType type) {
|
|
||||||
mStack.Add(new sunScope(type));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public void Pop() {
|
public void Pop() {
|
||||||
if (Count > 1) {
|
if (Count > 1) {
|
||||||
#if SSC_SCOPES
|
|
||||||
if (Top.Type == sunScopeType.Script) {
|
|
||||||
mLocals = 0; // left the function, reset locals
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// close relocations while we still have references to the symbols
|
// close relocations while we still have references to the symbols
|
||||||
foreach (var variable in Top) {
|
foreach (var variable in Top) {
|
||||||
variable.CloseRelocations();
|
variable.CloseRelocations();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
mStack.RemoveAt(Count - 1);
|
mStack.RemoveAt(Count - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Clear() {
|
public void Clear() {
|
||||||
mStack.Clear();
|
mStack.Clear();
|
||||||
#if SSC_SCOPES
|
|
||||||
Push(sunScopeType.Script); // add global scope
|
|
||||||
mLocals = 0;
|
|
||||||
#else
|
|
||||||
Push();
|
Push();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sunVariableSymbol DeclareVariable(string name) {
|
public sunVariableSymbol DeclareVariable(string name) {
|
||||||
#if SSC_SCOPES
|
|
||||||
switch (Top.Type) {
|
|
||||||
case sunScopeType.Script: return DeclareGlobal(name);
|
|
||||||
case sunScopeType.Function: return DeclareLocal(name);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
#else
|
|
||||||
return Top.DeclareVariable(name, Count - 1, Top.VariableCount);
|
return Top.DeclareVariable(name, Count - 1, Top.VariableCount);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
public sunConstantSymbol DeclareConstant(string name, sunExpression expression) {
|
public sunConstantSymbol DeclareConstant(string name, sunExpression expression) {
|
||||||
return Top.DeclareConstant(name, expression);
|
return Top.DeclareConstant(name, expression);
|
||||||
}
|
}
|
||||||
#if SSC_SCOPES
|
|
||||||
sunVariableSymbol DeclareGlobal(string name) {
|
|
||||||
// symbol's display/index will be
|
|
||||||
// filled out by the relocation code
|
|
||||||
return Top.DeclareVariable(name, 0, 0);
|
|
||||||
}
|
|
||||||
sunVariableSymbol DeclareLocal(string name) {
|
|
||||||
var symbol = Top.DeclareVariable(name, 1, mLocals);
|
|
||||||
if (symbol != null) {
|
|
||||||
++mLocals;
|
|
||||||
}
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public IEnumerator<sunScope> GetEnumerator() {
|
public IEnumerator<sunScope> GetEnumerator() {
|
||||||
return mStack.GetEnumerator();
|
return mStack.GetEnumerator();
|
||||||
|
@ -117,25 +57,9 @@ namespace arookas {
|
||||||
|
|
||||||
class sunScope : IEnumerable<sunStorableSymbol> {
|
class sunScope : IEnumerable<sunStorableSymbol> {
|
||||||
List<sunStorableSymbol> mStorables;
|
List<sunStorableSymbol> mStorables;
|
||||||
#if SSC_SCOPES
|
|
||||||
sunScopeType mType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SSC_SCOPES
|
|
||||||
public sunScopeType Type {
|
|
||||||
get { return mType; }
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SSC_SCOPES
|
|
||||||
public sunScope(sunScopeType type) {
|
|
||||||
#else
|
|
||||||
public sunScope() {
|
public sunScope() {
|
||||||
#endif
|
|
||||||
mStorables = new List<sunStorableSymbol>(10);
|
mStorables = new List<sunStorableSymbol>(10);
|
||||||
#if SSC_SCOPES
|
|
||||||
mType = type;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int StorableCount {
|
public int StorableCount {
|
||||||
|
@ -186,11 +110,4 @@ namespace arookas {
|
||||||
return GetEnumerator();
|
return GetEnumerator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SSC_SCOPES
|
|
||||||
enum sunScopeType {
|
|
||||||
Script,
|
|
||||||
Function,
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,11 +185,7 @@ namespace arookas {
|
||||||
|
|
||||||
public override void Compile(sunCompiler compiler) {
|
public override void Compile(sunCompiler compiler) {
|
||||||
mOffset = compiler.Binary.Offset;
|
mOffset = compiler.Binary.Offset;
|
||||||
#if SSC_SCOPES
|
|
||||||
compiler.Context.Scopes.Push(sunScopeType.Function);
|
|
||||||
#else
|
|
||||||
compiler.Context.Scopes.Push();
|
compiler.Context.Scopes.Push();
|
||||||
#endif
|
|
||||||
foreach (var parameter in Parameters) {
|
foreach (var parameter in Parameters) {
|
||||||
compiler.Context.Scopes.DeclareVariable(parameter); // since there is no AST node for these, they won't affect MaxLocalCount
|
compiler.Context.Scopes.DeclareVariable(parameter); // since there is no AST node for these, they won't affect MaxLocalCount
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue