Complete overhaul of binary-writing system

- Merged sunWriter and binary-writing code from sunContext into
sunBinary
- Changed compilation functions to take sunCompiler instance instead of
a sunContext
- Completely removed links between context and binary
- Moved import logic to sunCompiler
- Made sunContext and sunBinary properties on sunCompiler so compilation
functions can access them
This commit is contained in:
arookas 2016-01-31 20:03:12 -05:00
parent 8f683d16a3
commit eb3e679fc7
16 changed files with 669 additions and 559 deletions

View file

@ -2,8 +2,7 @@
using System.Collections;
using System.Collections.Generic;
namespace arookas
{
namespace arookas {
public class sunSourceLocation {
public string File { get; private set; }
public int Line { get; private set; }
@ -36,8 +35,8 @@ namespace arookas
public int MaxLocalCount {
get {
int locals = 0;
int maxChildLocals = 0;
var locals = 0;
var maxChildLocals = 0;
foreach (var child in this) {
if (child is sunVariableDeclaration || child is sunVariableDefinition) {
++locals;
@ -46,7 +45,7 @@ namespace arookas
locals += child.MaxLocalCount; // HACK: compound statements aren't their own scope
}
else if (!(child is sunFunctionDefinition)) { // don't recurse into function bodies
int childLocals = child.MaxLocalCount;
var childLocals = child.MaxLocalCount;
if (childLocals > maxChildLocals) {
maxChildLocals = childLocals;
}
@ -87,20 +86,17 @@ namespace arookas
mChildren.Clear();
}
public virtual void Compile(sunContext context) {
// Simply compile all children nodes by default. This is here for the transcient nodes' implementations
// (sunStatement, sunCompoundStatement, etc.) so I only have to type this once. sunExpression is careful
// to override this with the custom shunting-yard algorithm implementation.
public virtual void Compile(sunCompiler compiler) {
foreach (var child in this) {
child.Compile(context);
child.Compile(compiler);
}
}
protected bool TryCompile(sunNode node, sunContext context) {
if (node != null) {
node.Compile(context);
return true;
protected bool TryCompile(sunNode node, sunCompiler compiler) {
if (node == null) {
return false;
}
return false;
node.Compile(compiler);
return true;
}
public IEnumerator<sunNode> GetEnumerator() { return mChildren.GetEnumerator(); }

View file

@ -12,15 +12,15 @@ namespace arookas {
public sunExpression(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
Stack<sunOperator> operatorStack = new Stack<sunOperator>(32);
CompileExpression(context, this, operatorStack);
public override void Compile(sunCompiler compiler) {
var operatorStack = new Stack<sunOperator>(32);
CompileExpression(compiler, this, operatorStack);
}
public sunExpressionFlags Analyze(sunContext context) {
return AnalyzeExpression(context, this);
}
static void CompileExpression(sunContext context, sunExpression expression, Stack<sunOperator> operatorStack) {
static void CompileExpression(sunCompiler compiler, sunExpression expression, Stack<sunOperator> operatorStack) {
// this implementation assumes that the expression production child list alternates between operand and operator
// we can safely assume this as the grammar "operand {binary_operator operand}" enforces it
int stackCount = operatorStack.Count;
@ -31,14 +31,14 @@ namespace arookas {
// term
var term = operand.Term;
if (term is sunExpression) {
CompileExpression(context, term as sunExpression, operatorStack);
CompileExpression(compiler, term as sunExpression, operatorStack);
}
else {
term.Compile(context);
term.Compile(compiler);
}
var unaryOperators = operand.UnaryOperators;
if (unaryOperators != null) {
unaryOperators.Compile(context);
unaryOperators.Compile(compiler);
}
}
else if (node is sunOperator) {
@ -46,17 +46,17 @@ namespace arookas {
while (operatorStack.Count > stackCount &&
(operatorNode.IsLeftAssociative && operatorNode.Precedence <= operatorStack.Peek().Precedence) ||
(operatorNode.IsRightAssociative && operatorNode.Precedence < operatorStack.Peek().Precedence)) {
operatorStack.Pop().Compile(context);
operatorStack.Pop().Compile(compiler);
}
operatorStack.Push(operatorNode);
}
}
while (operatorStack.Count > stackCount) {
operatorStack.Pop().Compile(context);
operatorStack.Pop().Compile(compiler);
}
}
static sunExpressionFlags AnalyzeExpression(sunContext context, sunExpression expression) {
sunExpressionFlags flags = sunExpressionFlags.None;
var flags = sunExpressionFlags.None;
foreach (var operand in expression.OfType<sunOperand>()) {
var term = operand.Term as sunTerm;
if (term != null) {
@ -100,10 +100,10 @@ namespace arookas {
public sunUnaryOperatorList(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
public override void Compile(sunCompiler compiler) {
foreach (var child in this.Reverse()) {
// compile unary operators in reverse order
child.Compile(context);
child.Compile(compiler);
}
}
}
@ -116,14 +116,14 @@ namespace arookas {
public sunTernaryOperator(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
Condition.Compile(context);
var falsePrologue = context.Text.WriteJNE();
TrueBody.Compile(context);
var trueEpilogue = context.Text.WriteJMP();
context.Text.ClosePoint(falsePrologue);
FalseBody.Compile(context);
context.Text.ClosePoint(trueEpilogue);
public override void Compile(sunCompiler compiler) {
Condition.Compile(compiler);
var falsePrologue = compiler.Binary.WriteJNE();
TrueBody.Compile(compiler);
var trueEpilogue = compiler.Binary.WriteJMP();
compiler.Binary.ClosePoint(falsePrologue);
FalseBody.Compile(compiler);
compiler.Binary.ClosePoint(trueEpilogue);
}
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
@ -139,15 +139,15 @@ namespace arookas {
public sunPostfixAugment(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var symbol = context.MustResolveStorable(Variable);
public override void Compile(sunCompiler compiler) {
var symbol = compiler.Context.MustResolveStorable(Variable);
if (symbol is sunConstantSymbol) {
throw new sunAssignConstantException(Variable);
}
if (Parent is sunOperand) {
symbol.CompileGet(context);
symbol.CompileGet(compiler);
}
Augment.Compile(context, symbol);
Augment.Compile(compiler, symbol);
}
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
@ -162,14 +162,14 @@ namespace arookas {
public sunPrefixAugment(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var symbol = context.MustResolveStorable(Variable);
public override void Compile(sunCompiler compiler) {
var symbol = compiler.Context.MustResolveStorable(Variable);
if (symbol is sunConstantSymbol) {
throw new sunAssignConstantException(Variable);
}
Augment.Compile(context, symbol);
Augment.Compile(compiler, symbol);
if (Parent is sunOperand) {
symbol.CompileGet(context);
symbol.CompileGet(compiler);
}
}
@ -182,16 +182,16 @@ namespace arookas {
protected sunAugment(sunSourceLocation location)
: base(location) { }
public abstract void Compile(sunContext context, sunStorableSymbol symbol);
public abstract void Compile(sunCompiler compiler, sunStorableSymbol symbol);
}
class sunIncrement : sunAugment {
public sunIncrement(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol) {
symbol.CompileInc(context);
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol) {
symbol.CompileInc(compiler);
symbol.CompileSet(compiler);
}
}
@ -199,9 +199,9 @@ namespace arookas {
public sunDecrement(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol) {
symbol.CompileDec(context);
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol) {
symbol.CompileDec(compiler);
symbol.CompileSet(compiler);
}
}
}

View file

@ -10,19 +10,19 @@ namespace arookas {
public sunIf(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
Condition.Compile(context);
var trueBodyEpilogue = context.Text.WriteJNE();
TrueBody.Compile(context);
public override void Compile(sunCompiler compiler) {
Condition.Compile(compiler);
var trueBodyEpilogue = compiler.Binary.WriteJNE();
TrueBody.Compile(compiler);
var falseBody = FalseBody;
if (falseBody != null) {
var falseBodyEpilogue = context.Text.WriteJMP();
context.Text.ClosePoint(trueBodyEpilogue);
falseBody.Compile(context);
context.Text.ClosePoint(falseBodyEpilogue);
var falseBodyEpilogue = compiler.Binary.WriteJMP();
compiler.Binary.ClosePoint(trueBodyEpilogue);
falseBody.Compile(compiler);
compiler.Binary.ClosePoint(falseBodyEpilogue);
}
else {
context.Text.ClosePoint(trueBodyEpilogue);
compiler.Binary.ClosePoint(trueBodyEpilogue);
}
}
}
@ -54,17 +54,17 @@ namespace arookas {
public sunWhile(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var loop = PushLoop(context);
var bodyPrologue = context.Text.OpenPoint();
loop.ContinuePoint = context.Text.OpenPoint();
Condition.Compile(context);
var bodyEpilogue = context.Text.WriteJNE();
Body.Compile(context);
context.Text.WriteJMP(bodyPrologue);
context.Text.ClosePoint(bodyEpilogue);
loop.BreakPoint = context.Text.OpenPoint();
context.Loops.Pop(context);
public override void Compile(sunCompiler compiler) {
var loop = PushLoop(compiler.Context);
var bodyPrologue = compiler.Binary.OpenPoint();
loop.ContinuePoint = compiler.Binary.OpenPoint();
Condition.Compile(compiler);
var bodyEpilogue = compiler.Binary.WriteJNE();
Body.Compile(compiler);
compiler.Binary.WriteJMP(bodyPrologue);
compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint();
compiler.Context.Loops.Pop(compiler);
}
}
@ -75,17 +75,17 @@ namespace arookas {
public sunDo(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var loop = PushLoop(context);
var bodyPrologue = context.Text.OpenPoint();
Body.Compile(context);
loop.ContinuePoint = context.Text.OpenPoint();
Condition.Compile(context);
var bodyEpilogue = context.Text.WriteJNE();
context.Text.WriteJMP(bodyPrologue);
context.Text.ClosePoint(bodyEpilogue);
loop.BreakPoint = context.Text.OpenPoint();
context.Loops.Pop(context);
public override void Compile(sunCompiler compiler) {
var loop = PushLoop(compiler.Context);
var bodyPrologue = compiler.Binary.OpenPoint();
Body.Compile(compiler);
loop.ContinuePoint = compiler.Binary.OpenPoint();
Condition.Compile(compiler);
var bodyEpilogue = compiler.Binary.WriteJNE();
compiler.Binary.WriteJMP(bodyPrologue);
compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint();
compiler.Context.Loops.Pop(compiler);
}
}
@ -98,21 +98,21 @@ namespace arookas {
public sunFor(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.Scopes.Push();
var loop = PushLoop(context);
TryCompile(Declaration, context);
var bodyPrologue = context.Text.OpenPoint();
TryCompile(Condition, context);
var bodyEpilogue = context.Text.WriteJNE();
Body.Compile(context);
loop.ContinuePoint = context.Text.OpenPoint();
TryCompile(Iteration, context);
context.Text.WriteJMP(bodyPrologue);
context.Text.ClosePoint(bodyEpilogue);
loop.BreakPoint = context.Text.OpenPoint();
context.Loops.Pop(context);
context.Scopes.Pop();
public override void Compile(sunCompiler compiler) {
compiler.Context.Scopes.Push();
var loop = PushLoop(compiler.Context);
TryCompile(Declaration, compiler);
var bodyPrologue = compiler.Binary.OpenPoint();
TryCompile(Condition, compiler);
var bodyEpilogue = compiler.Binary.WriteJNE();
Body.Compile(compiler);
loop.ContinuePoint = compiler.Binary.OpenPoint();
TryCompile(Iteration, compiler);
compiler.Binary.WriteJMP(bodyPrologue);
compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint();
compiler.Context.Loops.Pop(compiler);
compiler.Context.Scopes.Pop();
}
}
class sunForDeclaration : sunNode {
@ -134,14 +134,14 @@ namespace arookas {
public sunReturn(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
public override void Compile(sunCompiler compiler) {
var expression = Expression;
if (expression != null) {
expression.Compile(context);
context.Text.WriteRET();
expression.Compile(compiler);
compiler.Binary.WriteRET();
}
else {
context.Text.WriteRET0();
compiler.Binary.WriteRET0();
}
}
}
@ -153,9 +153,9 @@ namespace arookas {
public sunBreak(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var point = context.Text.WriteJMP();
if (!context.Loops.AddBreak(point, IsNamed ? NameLabel.Value : null)) {
public override void Compile(sunCompiler compiler) {
var point = compiler.Binary.WriteJMP();
if (!compiler.Context.Loops.AddBreak(point, IsNamed ? NameLabel.Value : null)) {
throw new sunBreakException(this);
}
}
@ -168,9 +168,9 @@ namespace arookas {
public sunContinue(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var point = context.Text.WriteJMP();
if (!context.Loops.AddContinue(point, IsNamed ? NameLabel.Value : null)) {
public override void Compile(sunCompiler compiler) {
var point = compiler.Binary.WriteJMP();
if (!compiler.Context.Loops.AddContinue(point, IsNamed ? NameLabel.Value : null)) {
throw new sunContinueException(this);
}
}

View file

@ -9,8 +9,8 @@ namespace arookas {
public sunBuiltinDeclaration(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.DeclareBuiltin(this);
public override void Compile(sunCompiler compiler) {
compiler.Context.DeclareBuiltin(this);
}
}
@ -22,8 +22,10 @@ namespace arookas {
public sunFunctionDefinition(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.DefineFunction(this); // possibly counter intuitively, this defines the function in the context; it doesn't compile the definition body
public override void Compile(sunCompiler compiler) {
// this defines the function in the context
// it doesn't compile the definition body
compiler.Context.DefineFunction(this);
}
}
@ -36,15 +38,15 @@ namespace arookas {
public sunFunctionCall(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var symbol = context.MustResolveCallable(this);
public override void Compile(sunCompiler compiler) {
var symbol = compiler.Context.MustResolveCallable(this);
if (!symbol.Parameters.ValidateArgumentCount(Arguments.Count)) {
throw new sunArgumentCountException(this, symbol);
}
Arguments.Compile(context);
symbol.OpenCallSite(context, Arguments.Count);
Arguments.Compile(compiler);
symbol.OpenCallSite(compiler, Arguments.Count);
if (IsStatement) {
context.Text.WritePOP();
compiler.Binary.WritePOP();
}
}

View file

@ -13,7 +13,9 @@ namespace arookas {
protected sunIntLiteral(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteINT(Value); }
public override void Compile(sunCompiler compiler) {
compiler.Binary.WriteINT(Value);
}
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
return sunExpressionFlags.Literals;
@ -41,8 +43,8 @@ namespace arookas {
Value = Single.Parse(literal);
}
public override void Compile(sunContext context) {
context.Text.WriteFLT(Value);
public override void Compile(sunCompiler compiler) {
compiler.Binary.WriteFLT(Value);
}
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
@ -56,8 +58,9 @@ namespace arookas {
Value = UnescapeString(literal.Substring(1, literal.Length - 2)); // remove enclosing quotes
}
public override void Compile(sunContext context) {
context.Text.WriteSTR(context.DataTable.Add(Value));
public override void Compile(sunCompiler compiler) {
var index = compiler.Context.DataTable.Add(Value);
compiler.Binary.WriteSTR(index);
}
// string unescaping utility

View file

@ -24,7 +24,7 @@ namespace arookas {
public sunLogOR(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteOR(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteOR(); }
}
// precedence 1
@ -34,7 +34,7 @@ namespace arookas {
public sunLogAND(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteAND(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteAND(); }
}
// precedence 2
@ -44,7 +44,7 @@ namespace arookas {
public sunBitOR(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteBOR(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteBOR(); }
}
// precedence 3
@ -54,7 +54,7 @@ namespace arookas {
public sunBitAND(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteBAND(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteBAND(); }
}
// precedence 4
@ -64,7 +64,7 @@ namespace arookas {
public sunEq(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteEQ(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteEQ(); }
}
class sunNtEq : sunOperator {
@ -73,7 +73,7 @@ namespace arookas {
public sunNtEq(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteNE(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteNE(); }
}
// precedence 5
@ -83,7 +83,7 @@ namespace arookas {
public sunLt(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteLT(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteLT(); }
}
class sunLtEq : sunOperator {
@ -92,7 +92,7 @@ namespace arookas {
public sunLtEq(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteLE(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteLE(); }
}
class sunGt : sunOperator {
@ -101,7 +101,7 @@ namespace arookas {
public sunGt(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteGT(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteGT(); }
}
class sunGtEq : sunOperator {
@ -110,7 +110,7 @@ namespace arookas {
public sunGtEq(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteGE(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteGE(); }
}
// precedence 6
@ -120,7 +120,7 @@ namespace arookas {
public sunBitLsh(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteSHL(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteSHL(); }
}
class sunBitRsh : sunOperator {
@ -129,7 +129,7 @@ namespace arookas {
public sunBitRsh(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteSHR(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteSHR(); }
}
// precedence 7
@ -139,7 +139,7 @@ namespace arookas {
public sunAdd(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteADD(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteADD(); }
}
class sunSub : sunOperator {
@ -148,7 +148,7 @@ namespace arookas {
public sunSub(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteSUB(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteSUB(); }
}
// precedence 8
@ -158,7 +158,7 @@ namespace arookas {
public sunMul(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteMUL(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteMUL(); }
}
class sunDiv : sunOperator {
@ -167,7 +167,7 @@ namespace arookas {
public sunDiv(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteDIV(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteDIV(); }
}
class sunMod : sunOperator {
@ -176,7 +176,7 @@ namespace arookas {
public sunMod(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteMOD(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteMOD(); }
}
// precedence 9
@ -186,7 +186,7 @@ namespace arookas {
public sunLogNOT(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteNOT(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteNOT(); }
}
class sunNeg : sunOperator {
public override int Precedence { get { return 9; } }
@ -194,7 +194,7 @@ namespace arookas {
public sunNeg(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) { context.Text.WriteNEG(); }
public override void Compile(sunCompiler compiler) { compiler.Binary.WriteNEG(); }
}
// assignment operators
@ -205,9 +205,9 @@ namespace arookas {
public sunAssign(sunSourceLocation location)
: base(location) { }
public virtual void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
expression.Compile(context);
symbol.CompileSet(context);
public virtual void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
expression.Compile(compiler);
symbol.CompileSet(compiler);
}
}
@ -215,11 +215,11 @@ namespace arookas {
public sunAssignAdd(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteADD();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteADD();
symbol.CompileSet(compiler);
}
}
@ -227,11 +227,11 @@ namespace arookas {
public sunAssignSub(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteSUB();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteSUB();
symbol.CompileSet(compiler);
}
}
@ -239,11 +239,11 @@ namespace arookas {
public sunAssignMul(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteMUL();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteMUL();
symbol.CompileSet(compiler);
}
}
@ -251,11 +251,11 @@ namespace arookas {
public sunAssignDiv(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteDIV();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteDIV();
symbol.CompileSet(compiler);
}
}
@ -263,11 +263,11 @@ namespace arookas {
public sunAssignMod(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteMOD();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteMOD();
symbol.CompileSet(compiler);
}
}
@ -275,11 +275,11 @@ namespace arookas {
public sunAssignBitAND(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteBAND();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteBAND();
symbol.CompileSet(compiler);
}
}
@ -287,11 +287,11 @@ namespace arookas {
public sunAssignBitOR(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteBOR();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteBOR();
symbol.CompileSet(compiler);
}
}
@ -299,11 +299,11 @@ namespace arookas {
public sunAssignBitLsh(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteSHL();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteSHL();
symbol.CompileSet(compiler);
}
}
@ -311,11 +311,11 @@ namespace arookas {
public sunAssignBitRsh(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(context);
expression.Compile(context);
context.Text.WriteSHR();
symbol.CompileSet(context);
public override void Compile(sunCompiler compiler, sunStorableSymbol symbol, sunExpression expression) {
symbol.CompileGet(compiler);
expression.Compile(compiler);
compiler.Binary.WriteSHR();
symbol.CompileSet(compiler);
}
}
}

View file

@ -8,10 +8,10 @@
public sunStatementBlock(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.Scopes.Push(context.Scopes.Top.Type);
base.Compile(context);
context.Scopes.Pop();
public override void Compile(sunCompiler compiler) {
compiler.Context.Scopes.Push(compiler.Context.Scopes.Top.Type);
base.Compile(compiler);
compiler.Context.Scopes.Pop();
}
}
@ -21,11 +21,13 @@
public sunImport(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var result = context.Import(ImportFile.Value);
public override void Compile(sunCompiler compiler) {
var result = compiler.Import(ImportFile.Value);
switch (result) {
case sunImportResult.Missing:
case sunImportResult.FailedToLoad: throw new sunMissingImportException(this);
case sunImportResult.FailedToLoad: {
throw new sunMissingImportException(this);
}
}
}
}
@ -36,8 +38,8 @@
public sunNameLabel(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.PushNameLabel(this);
public override void Compile(sunCompiler compiler) {
compiler.Context.PushNameLabel(this);
}
}
}

View file

@ -3,9 +3,9 @@
public sunYield(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.Yield.OpenCallSite(context, 0);
context.Text.WritePOP();
public override void Compile(sunCompiler compiler) {
compiler.Context.Yield.OpenCallSite(compiler, 0);
compiler.Binary.WritePOP();
}
}
@ -13,9 +13,9 @@
public sunExit(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.Exit.OpenCallSite(context, 0);
context.Text.WritePOP();
public override void Compile(sunCompiler compiler) {
compiler.Context.Exit.OpenCallSite(compiler, 0);
compiler.Binary.WritePOP();
}
}
@ -23,9 +23,9 @@
public sunLock(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.Lock.OpenCallSite(context, 0);
context.Text.WritePOP();
public override void Compile(sunCompiler compiler) {
compiler.Context.Lock.OpenCallSite(compiler, 0);
compiler.Binary.WritePOP();
}
}
@ -33,9 +33,9 @@
public sunUnlock(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.Unlock.OpenCallSite(context, 0);
context.Text.WritePOP();
public override void Compile(sunCompiler compiler) {
compiler.Context.Unlock.OpenCallSite(compiler, 0);
compiler.Binary.WritePOP();
}
}
@ -54,9 +54,9 @@
public sunIntCast(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
Argument.Compile(context);
context.Int.OpenCallSite(context, 1);
public override void Compile(sunCompiler compiler) {
Argument.Compile(compiler);
compiler.Context.Int.OpenCallSite(compiler, 1);
}
}
@ -64,9 +64,9 @@
public sunFloatCast(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
Argument.Compile(context);
context.Float.OpenCallSite(context, 1);
public override void Compile(sunCompiler compiler) {
Argument.Compile(compiler);
compiler.Context.Float.OpenCallSite(compiler, 1);
}
}
@ -74,9 +74,9 @@
public sunTypeofCast(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
Argument.Compile(context);
context.Typeof.OpenCallSite(context, 1);
public override void Compile(sunCompiler compiler) {
Argument.Compile(compiler);
compiler.Context.Typeof.OpenCallSite(compiler, 1);
}
}
}

View file

@ -5,8 +5,8 @@
public sunStorableReference(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.MustResolveStorable(Storable).Compile(context);
public override void Compile(sunCompiler compiler) {
compiler.Context.MustResolveStorable(Storable).Compile(compiler);
}
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
@ -27,13 +27,12 @@
public sunVariableDeclaration(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
context.DeclareVariable(Variable);
public override void Compile(sunCompiler compiler) {
compiler.Context.DeclareVariable(Variable);
}
}
class sunVariableDefinition : sunNode
{
class sunVariableDefinition : sunNode {
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
public sunAssign Operator { get { return this[1] as sunAssign; } }
public sunExpression Expression { get { return this[2] as sunExpression; } }
@ -41,14 +40,13 @@
public sunVariableDefinition(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var symbol = context.DeclareVariable(Variable);
Operator.Compile(context, symbol, Expression);
public override void Compile(sunCompiler compiler) {
var symbol = compiler.Context.DeclareVariable(Variable);
Operator.Compile(compiler, symbol, Expression);
}
}
class sunStorableAssignment : sunNode
{
class sunStorableAssignment : sunNode {
public sunIdentifier Storable { get { return this[0] as sunIdentifier; } }
public sunAssign Operator { get { return this[1] as sunAssign; } }
public sunExpression Expression { get { return this[2] as sunExpression; } }
@ -56,32 +54,31 @@
public sunStorableAssignment(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
var symbol = context.MustResolveStorable(Storable);
public override void Compile(sunCompiler compiler) {
var symbol = compiler.Context.MustResolveStorable(Storable);
if (symbol is sunConstantSymbol) {
throw new sunAssignConstantException(Storable);
}
Operator.Compile(context, symbol, Expression);
Operator.Compile(compiler, symbol, Expression);
}
}
class sunConstantDefinition : sunNode
{
class sunConstantDefinition : sunNode {
public sunIdentifier Constant { get { return this[0] as sunIdentifier; } }
public sunExpression Expression { get { return this[2] as sunExpression; } }
public sunConstantDefinition(sunSourceLocation location)
: base(location) { }
public override void Compile(sunContext context) {
// analyze the expression first. this does two things:
public override void Compile(sunCompiler compiler) {
// analyze the expression. this does two things:
// 1) prevents recursion (i.e. the const referencing itself)
// 2) asserts actual constness
var flags = Expression.Analyze(context);
var flags = Expression.Analyze(compiler.Context);
if (flags.HasFlag(sunExpressionFlags.Dynamic)) {
throw new sunConstantExpressionException(Expression);
}
context.DeclareConstant(Constant, Expression);
compiler.Context.DeclareConstant(Constant, Expression);
}
}
}

319
ssc/binary.cs Normal file
View file

@ -0,0 +1,319 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using arookas.IO.Binary;
namespace arookas {
class sunBinary : IDisposable {
aBinaryWriter mWriter;
sunBinarySection mText, mData, mDataString, mSymbol, mSymbolString;
int mDataCount, mSymbolCount, mVarCount;
public uint Offset {
get { return mText.Offset; }
}
public sunBinary(Stream output) {
mWriter = new aBinaryWriter(output, Endianness.Big, Encoding.GetEncoding(932));
mText = new sunBinarySection();
mData = new sunBinarySection();
mDataString = new sunBinarySection();
mSymbol = new sunBinarySection();
mSymbolString = new sunBinarySection();
mWriter.PushAnchor();
}
// close
public void Dispose() {
Close();
}
public void Close() {
// header
mWriter.WriteString("SPCB");
mWriter.Write32(0x1C);
mWriter.Write32(0x1C + mText.Size);
mWriter.WriteS32(mDataCount);
mWriter.Write32(0x1C + mText.Size + mData.Size + mDataString.Size);
mWriter.WriteS32(mSymbolCount);
mWriter.WriteS32(mVarCount);
// sections
mText.Copy(mWriter);
mData.Copy(mWriter);
mDataString.Copy(mWriter);
mSymbol.Copy(mWriter);
mSymbolString.Copy(mWriter);
}
// text
public void Keep() {
mText.Writer.Keep();
}
public void Back() {
mText.Writer.Back();
}
public void Goto(uint offset) {
mText.Writer.Goto(offset);
}
public sunPoint OpenPoint() {
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
case 0: WriteINT0(); return;
case 1: WriteINT1(); return;
}
mText.Writer.Write8(0x00);
mText.Writer.WriteS32(value);
}
public void WriteFLT(float value) {
mText.Writer.Write8(0x01);
mText.Writer.WriteF32(value);
}
public void WriteSTR(int index) {
mText.Writer.Write8(0x02);
mText.Writer.WriteS32(index);
}
public void WriteADR(int value) {
mText.Writer.Write8(0x03);
mText.Writer.WriteS32(value);
}
public void WriteVAR(int display, int index) {
mText.Writer.Write8(0x04);
mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index);
}
public void WriteNOP() {
mText.Writer.Write8(0x05);
}
public void WriteINC(int display, int index) {
mText.Writer.Write8(0x06);
mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index);
}
public void WriteDEC(int display, int index) {
mText.Writer.Write8(0x07);
mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index);
}
public void WriteADD() {
mText.Writer.Write8(0x08);
}
public void WriteSUB() {
mText.Writer.Write8(0x09);
}
public void WriteMUL() {
mText.Writer.Write8(0x0A);
}
public void WriteDIV() {
mText.Writer.Write8(0x0B);
}
public void WriteMOD() {
mText.Writer.Write8(0x0C);
}
public void WriteASS(int display, int index) {
mText.Writer.Write8(0x0D);
mText.Writer.Write8(0x04); // unused (skipped over by TSpcInterp)
mText.Writer.WriteS32(display);
mText.Writer.WriteS32(index);
}
public void WriteEQ() {
mText.Writer.Write8(0x0E);
}
public void WriteNE() {
mText.Writer.Write8(0x0F);
}
public void WriteGT() {
mText.Writer.Write8(0x10);
}
public void WriteLT() {
mText.Writer.Write8(0x11);
}
public void WriteGE() {
mText.Writer.Write8(0x12);
}
public void WriteLE() {
mText.Writer.Write8(0x13);
}
public void WriteNEG() {
mText.Writer.Write8(0x14);
}
public void WriteNOT() {
mText.Writer.Write8(0x15);
}
public void WriteAND() {
mText.Writer.Write8(0x16);
}
public void WriteOR() {
mText.Writer.Write8(0x17);
}
public void WriteBAND() {
mText.Writer.Write8(0x18);
}
public void WriteBOR() {
mText.Writer.Write8(0x19);
}
public void WriteSHL() {
mText.Writer.Write8(0x1A);
}
public void WriteSHR() {
mText.Writer.Write8(0x1B);
}
public sunPoint WriteCALL(int count) {
mText.Writer.Write8(0x1C);
sunPoint point = OpenPoint();
mText.Writer.Write32(0); // dummy
mText.Writer.WriteS32(count);
return point;
}
public void WriteCALL(sunPoint point, int count) {
mText.Writer.Write8(0x1C);
mText.Writer.Write32(point.Offset);
mText.Writer.WriteS32(count);
}
public void WriteFUNC(int index, int count) {
mText.Writer.Write8(0x1D);
mText.Writer.WriteS32(index);
mText.Writer.WriteS32(count);
}
public void WriteMKFR(int count) {
mText.Writer.Write8(0x1E);
mText.Writer.WriteS32(count);
}
public void WriteMKDS(int display) {
mText.Writer.Write8(0x1F);
mText.Writer.WriteS32(display);
}
public void WriteRET() {
mText.Writer.Write8(0x20);
}
public void WriteRET0() {
mText.Writer.Write8(0x21);
}
public sunPoint WriteJNE() {
mText.Writer.Write8(0x22);
sunPoint point = OpenPoint();
mText.Writer.Write32(0); // dummy
return point;
}
public void WriteJNE(sunPoint point) {
mText.Writer.Write8(0x22);
mText.Writer.Write32(point.Offset);
}
public sunPoint WriteJMP() {
mText.Writer.Write8(0x23);
sunPoint point = OpenPoint();
mText.Writer.Write32(0); // dummy
return point;
}
public void WriteJMP(sunPoint point) {
mText.Writer.Write8(0x23);
mText.Writer.Write32(point.Offset);
}
public void WritePOP() {
mText.Writer.Write8(0x24);
}
public void WriteINT0() {
mText.Writer.Write8(0x25);
}
public void WriteINT1() {
mText.Writer.Write8(0x26);
}
public void WriteEND() {
mText.Writer.Write8(0x27);
}
// data
public void WriteData(string data) {
if (data == null) {
throw new ArgumentNullException("data");
}
mData.Writer.Write32(mDataString.Size);
mDataString.Writer.WriteString(data, aBinaryStringFormat.NullTerminated);
++mDataCount;
}
// symbol
public void WriteSymbol(sunSymbol symbol) {
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.Write32(mSymbolString.Size);
mSymbol.Writer.Write32(data);
mSymbol.Writer.Write32(0u); // runtime field (hash)
mSymbol.Writer.Write32(0u); // runtime field (funcptr)
mSymbolString.Writer.WriteString(name, aBinaryStringFormat.NullTerminated);
++mSymbolCount;
if (type == sunSymbolType.Variable) {
++mVarCount;
}
}
class sunBinarySection : IDisposable {
readonly aBinaryWriter mWriter;
readonly MemoryStream mStream;
public aBinaryWriter Writer {
get { return mWriter; }
}
public MemoryStream Stream {
get { return mStream; }
}
public uint Offset {
get { return (uint)mWriter.Position; }
}
public uint Size {
get { return (uint)mWriter.Length; }
}
public sunBinarySection() {
mStream = new MemoryStream(1024);
mWriter = new aBinaryWriter(mStream, Endianness.Big, Encoding.GetEncoding(932));
}
public void Dispose() {
mWriter.Dispose();
mStream.Dispose();
}
public void Copy(aBinaryWriter writer) {
if (writer == null) {
throw new ArgumentNullException("writer");
}
writer.Write8s(mStream.GetBuffer(), (int)Size);
}
}
}
struct sunPoint {
readonly uint mOffset;
public uint Offset {
get { return mOffset; }
}
public sunPoint(uint offset) {
mOffset = offset;
}
public static implicit operator uint(sunPoint point) {
return point.mOffset;
}
}
}

View file

@ -4,6 +4,20 @@ using System.IO;
namespace arookas {
public class sunCompiler {
sunContext mContext;
sunBinary mBinary;
sunImportResolver mResolver;
internal sunContext Context {
get { return mContext; }
}
internal sunBinary Binary {
get { return mBinary; }
}
internal sunImportResolver ImportResolver {
get { return mResolver; }
}
public sunCompilerResults Compile(string name, Stream output) {
return Compile(name, output, sunImportResolver.Default);
}
@ -17,28 +31,35 @@ namespace arookas {
if (resolver == null) {
throw new ArgumentNullException("resolver");
}
var context = new sunContext();
var results = new sunCompilerResults();
var timer = Stopwatch.StartNew();
try {
context.Open(output, resolver);
var result = context.Import(name);
if (result != sunImportResult.Loaded) {
throw new sunImportException(name, result);
mResolver = resolver;
mContext = new sunContext();
using (mBinary = new sunBinary(output)) {
var result = Import(name);
if (result != sunImportResult.Loaded) {
throw new sunImportException(name, result);
}
mBinary.WriteEND(); // NOTETOSELF: don't do this via sunNode.Compile because imported files will add this as well
foreach (var callable in mContext.SymbolTable.Callables) {
callable.Compile(this);
}
foreach (var callable in mContext.SymbolTable.Callables) {
callable.CloseCallSites(this);
}
foreach (var data in mContext.DataTable) {
mBinary.WriteData(data);
}
foreach (var symbol in mContext.SymbolTable) {
mBinary.WriteSymbol(symbol.Type, symbol.Name, symbol.Data);
}
}
context.Text.WriteEND(); // NOTETOSELF: don't do this via sunNode.Compile because imported files will add this as well
foreach (var function in context.SymbolTable.Functions) {
function.Compile(context);
}
foreach (var callable in context.SymbolTable.Callables) {
callable.CloseCallSites(context);
}
results.DataCount = context.DataTable.Count;
results.SymbolCount = context.SymbolTable.Count;
results.BuiltinCount = context.SymbolTable.BuiltinCount;
results.FunctionCount = context.SymbolTable.FunctionCount;
results.VariableCount = context.SymbolTable.VariableCount;
context.Close();
results.DataCount = mContext.DataTable.Count;
results.SymbolCount = mContext.SymbolTable.Count;
results.BuiltinCount = mContext.SymbolTable.BuiltinCount;
results.FunctionCount = mContext.SymbolTable.FunctionCount;
results.VariableCount = mContext.SymbolTable.VariableCount;
}
catch (sunCompilerException ex) {
results.Error = ex;
@ -47,6 +68,27 @@ namespace arookas {
results.CompileTime = timer.Elapsed;
return results;
}
internal sunImportResult Import(string name) {
if (name == null) {
throw new ArgumentNullException("name");
}
sunScriptFile file;
var result = ImportResolver.ResolveImport(name, out file);
if (result == sunImportResult.Loaded) {
try {
ImportResolver.EnterFile(file);
var parser = new sunParser();
var tree = parser.Parse(file);
tree.Compile(this);
ImportResolver.ExitFile(file);
}
finally {
file.Dispose();
}
}
return result;
}
}
public class sunCompilerResults {

View file

@ -7,17 +7,12 @@ using System.Text;
namespace arookas {
class sunContext {
bool mOpen;
aBinaryWriter mWriter;
uint mTextOffset, mDataOffset, mSymbolOffset;
Stack<sunNameLabel> mNameStack;
public sunWriter Text { get; private set; }
public sunDataTable DataTable { get; private set; }
public sunSymbolTable SymbolTable { get; private set; }
public sunScopeStack Scopes { get; private set; }
public sunLoopStack Loops { get; private set; }
public sunImportResolver ImportResolver { get; private set; }
// system builtins
public sunCallableSymbol Yield { get; private set; }
@ -37,73 +32,18 @@ namespace arookas {
Scopes = new sunScopeStack();
Loops = new sunLoopStack();
mNameStack = new Stack<sunNameLabel>(5);
AddSystemSymbols();
}
// open/close
public void Open(Stream output) { Open(output, sunImportResolver.Default); }
public void Open(Stream output, sunImportResolver importResolver) {
if (mOpen) {
throw new InvalidOperationException();
}
if (output == null) {
throw new ArgumentNullException("output");
}
if (importResolver == null) {
throw new ArgumentNullException("importResolver");
}
mOpen = true;
public void Clear() {
DataTable.Clear();
SymbolTable.Clear();
Scopes.Clear();
Loops.Clear();
mNameStack.Clear();
ImportResolver = importResolver;
mWriter = new aBinaryWriter(output, Endianness.Big, Encoding.GetEncoding(932));
Text = new sunWriter(mWriter);
mWriter.PushAnchor();
// reinstall system symbols
AddSystemSymbols();
WriteHeader(); // dummy header
// begin text block
mTextOffset = (uint)mWriter.Position;
mWriter.PushAnchor(); // match code offsets and writer offsets
}
public void Close() {
if (!mOpen) {
throw new InvalidOperationException();
}
mWriter.PopAnchor();
mDataOffset = (uint)mWriter.Position;
DataTable.Write(mWriter);
mSymbolOffset = (uint)mWriter.Position;
SymbolTable.Write(mWriter);
mWriter.Goto(0);
WriteHeader();
mOpen = false;
}
// imports/compilation
public sunImportResult Import(string name) {
if (name == null) {
throw new ArgumentNullException("name");
}
sunScriptFile file;
var result = ImportResolver.ResolveImport(name, out file);
if (result == sunImportResult.Loaded) {
try {
ImportResolver.EnterFile(file);
var parser = new sunParser();
var tree = parser.Parse(file);
tree.Compile(this);
ImportResolver.ExitFile(file);
}
finally {
file.Dispose();
}
}
return result;
}
// callables
@ -210,6 +150,7 @@ namespace arookas {
return symbol;
}
// name labels
public void PushNameLabel(sunNameLabel label) {
if (label == null) {
throw new ArgumentNullException("label");
@ -247,14 +188,5 @@ namespace arookas {
SymbolTable.Add(symbol);
return symbol;
}
void WriteHeader() {
mWriter.WriteString("SPCB");
mWriter.Write32(mTextOffset);
mWriter.Write32(mDataOffset);
mWriter.WriteS32(DataTable.Count);
mWriter.Write32(mSymbolOffset);
mWriter.WriteS32(SymbolTable.Count);
mWriter.WriteS32(SymbolTable.VariableCount);
}
}
}

View file

@ -1,5 +1,4 @@
using arookas.IO.Binary;
using System.Collections;
using System.Collections;
using System.Collections.Generic;
namespace arookas {
@ -18,18 +17,6 @@ namespace arookas {
}
public void Clear() { data.Clear(); }
public void Write(aBinaryWriter writer) {
int ofs = 0;
foreach (var value in this) {
writer.WriteS32(ofs);
var length = writer.Encoding.GetByteCount(value);
ofs += length + 1; // include terminator
}
foreach (var value in this) {
writer.WriteString(value, aBinaryStringFormat.NullTerminated);
}
}
public IEnumerator<string> GetEnumerator() { return data.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

View file

@ -33,11 +33,11 @@ namespace arookas {
mLoops.Push(loop);
return loop;
}
public void Pop(sunContext context) {
public void Pop(sunCompiler compiler) {
if (Count < 1) {
return;
}
mLoops.Pop().Close(context);
mLoops.Pop().Close(compiler);
}
public void Clear() {
@ -117,15 +117,15 @@ namespace arookas {
mContinues.Add(point);
return true;
}
public void Close(sunContext context) {
public void Close(sunCompiler compiler) {
if (HasFlag(sunLoopFlags.ConsumeBreak)) {
foreach (var b in mBreaks) {
context.Text.ClosePoint(b, mBreakPoint.Offset);
compiler.Binary.ClosePoint(b, mBreakPoint);
}
}
if (HasFlag(sunLoopFlags.ConsumeContinue)) {
foreach (var c in mContinues) {
context.Text.ClosePoint(c, mContinuePoint.Offset);
compiler.Binary.ClosePoint(c, mContinuePoint);
}
}
}

View file

@ -31,24 +31,6 @@ namespace arookas {
public void Add(sunSymbol symbol) { Symbols.Add(symbol); }
public void Clear() { Symbols.Clear(); }
public void Write(aBinaryWriter writer) {
int ofs = 0;
foreach (var sym in this) {
writer.WriteS32((int)sym.Type);
writer.WriteS32(ofs);
writer.Write32(sym.Data);
// runtime fields
writer.WriteS32(0);
writer.WriteS32(0);
ofs += writer.Encoding.GetByteCount(sym.Name) + 1; // include null terminator
}
foreach (var sym in this) {
writer.WriteString(sym.Name, aBinaryStringFormat.NullTerminated);
}
}
public IEnumerator<sunSymbol> GetEnumerator() { return Symbols.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
@ -64,7 +46,7 @@ namespace arookas {
Name = name;
}
public abstract void Compile(sunContext context);
public abstract void Compile(sunCompiler compiler);
}
abstract class sunCallableSymbol : sunSymbol {
@ -79,8 +61,8 @@ namespace arookas {
CallSites = new List<sunPoint>(10);
}
public abstract void OpenCallSite(sunContext context, int argumentCount);
public abstract void CloseCallSites(sunContext context);
public abstract void OpenCallSite(sunCompiler compiler, int argumentCount);
public abstract void CloseCallSites(sunCompiler compiler);
}
class sunBuiltinSymbol : sunCallableSymbol {
@ -99,13 +81,13 @@ namespace arookas {
Index = index;
}
public override void Compile(sunContext context) {
throw new InvalidOperationException("Cannot compile builtins.");
public override void Compile(sunCompiler compiler) {
// don't compile builtins
}
public override void OpenCallSite(sunContext context, int argumentCount) {
context.Text.WriteFUNC(Index, argumentCount);
public override void OpenCallSite(sunCompiler compiler, int argumentCount) {
compiler.Binary.WriteFUNC(Index, argumentCount);
}
public override void CloseCallSites(sunContext context) { }
public override void CloseCallSites(sunCompiler compiler) { }
}
class sunFunctionSymbol : sunCallableSymbol {
@ -121,26 +103,26 @@ namespace arookas {
Body = body;
}
public override void Compile(sunContext context) {
Offset = context.Text.Offset;
context.Scopes.Push(sunScopeType.Function);
context.Scopes.ResetLocalCount();
public override void Compile(sunCompiler compiler) {
Offset = compiler.Binary.Offset;
compiler.Context.Scopes.Push(sunScopeType.Function);
compiler.Context.Scopes.ResetLocalCount();
foreach (var parameter in Parameters) {
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
}
context.Text.WriteMKDS(1);
context.Text.WriteMKFR(Body.MaxLocalCount);
Body.Compile(context);
context.Text.WriteRET0();
context.Scopes.Pop();
compiler.Binary.WriteMKDS(1);
compiler.Binary.WriteMKFR(Body.MaxLocalCount);
Body.Compile(compiler);
compiler.Binary.WriteRET0();
compiler.Context.Scopes.Pop();
}
public override void OpenCallSite(sunContext context, int argumentCount) {
var point = context.Text.WriteCALL(argumentCount);
public override void OpenCallSite(sunCompiler compiler, int argumentCount) {
var point = compiler.Binary.WriteCALL(argumentCount);
CallSites.Add(point);
}
public override void CloseCallSites(sunContext context) {
public override void CloseCallSites(sunCompiler compiler) {
foreach (var callSite in CallSites) {
context.Text.ClosePoint(callSite, Offset);
compiler.Binary.ClosePoint(callSite, Offset);
}
}
}
@ -177,18 +159,20 @@ namespace arookas {
protected sunStorableSymbol(string name)
: base(name) { }
public override void Compile(sunContext context) { CompileGet(context); } // compile get by default
public abstract void CompileGet(sunContext context);
public abstract void CompileSet(sunContext context);
public virtual void CompileInc(sunContext context) {
CompileGet(context);
context.Text.WriteINT(1);
context.Text.WriteADD();
public override void Compile(sunCompiler compiler) {
CompileGet(compiler);
}
public virtual void CompileDec(sunContext context) {
CompileGet(context);
context.Text.WriteINT(1);
context.Text.WriteSUB();
public abstract void CompileGet(sunCompiler compiler);
public abstract void CompileSet(sunCompiler compiler);
public virtual void CompileInc(sunCompiler compiler) {
CompileGet(compiler);
compiler.Binary.WriteINT(1);
compiler.Binary.WriteADD();
}
public virtual void CompileDec(sunCompiler compiler) {
CompileGet(compiler);
compiler.Binary.WriteINT(1);
compiler.Binary.WriteSUB();
}
}
@ -206,10 +190,10 @@ namespace arookas {
Index = index;
}
public override void CompileGet(sunContext context) { context.Text.WriteVAR(Display, Index); }
public override void CompileSet(sunContext context) { context.Text.WriteASS(Display, Index); }
public override void CompileInc(sunContext context) { context.Text.WriteINC(Display, Index); }
public override void CompileDec(sunContext context) { context.Text.WriteDEC(Display, Index); }
public override void CompileGet(sunCompiler compiler) { compiler.Binary.WriteVAR(Display, Index); }
public override void CompileSet(sunCompiler compiler) { compiler.Binary.WriteASS(Display, Index); }
public override void CompileInc(sunCompiler compiler) { compiler.Binary.WriteINC(Display, Index); }
public override void CompileDec(sunCompiler compiler) { compiler.Binary.WriteDEC(Display, Index); }
}
class sunConstantSymbol : sunStorableSymbol {
@ -227,10 +211,10 @@ namespace arookas {
Expression = expression;
}
public override void CompileGet(sunContext context) {
Expression.Compile(context);
public override void CompileGet(sunCompiler compiler) {
Expression.Compile(compiler);
}
public override void CompileSet(sunContext context) {
public override void CompileSet(sunCompiler compiler) {
// checks against this have to be implemented at a higher level
throw new InvalidOperationException();
}

View file

@ -1,154 +0,0 @@
using arookas.IO.Binary;
namespace arookas {
class sunWriter {
aBinaryWriter mWriter;
public uint Offset { get { return (uint)mWriter.Position; } }
public sunWriter(aBinaryWriter writer) {
this.mWriter = writer;
}
public void Keep() {
mWriter.Keep();
}
public void Back() {
mWriter.Back();
}
public void Goto(uint offset) {
mWriter.Goto(offset);
}
public sunPoint OpenPoint() { return new sunPoint(Offset); }
public void ClosePoint(sunPoint point) { ClosePoint(point, (uint)mWriter.Position); }
public void ClosePoint(sunPoint point, uint offset) {
Keep();
Goto(point.Offset);
mWriter.Write32(offset);
Back();
}
public void WriteINT(int value) {
switch (value) { // shortcut commands
case 0: WriteINT0(); return;
case 1: WriteINT1(); return;
}
mWriter.Write8(0x00);
mWriter.WriteS32(value);
}
public void WriteFLT(float value) {
mWriter.Write8(0x01);
mWriter.WriteF32(value);
}
public void WriteSTR(int index) {
mWriter.Write8(0x02);
mWriter.WriteS32(index);
}
public void WriteADR(int value) {
mWriter.Write8(0x03);
mWriter.WriteS32(value);
}
public void WriteVAR(int display, int index) {
mWriter.Write8(0x04);
mWriter.WriteS32(display);
mWriter.WriteS32(index);
}
public void WriteNOP() { mWriter.Write8(0x05); }
public void WriteINC(int display, int index) {
mWriter.Write8(0x06);
mWriter.WriteS32(display);
mWriter.WriteS32(index);
}
public void WriteDEC(int display, int index) {
mWriter.Write8(0x07);
mWriter.WriteS32(display);
mWriter.WriteS32(index);
}
public void WriteADD() { mWriter.Write8(0x08); }
public void WriteSUB() { mWriter.Write8(0x09); }
public void WriteMUL() { mWriter.Write8(0x0A); }
public void WriteDIV() { mWriter.Write8(0x0B); }
public void WriteMOD() { mWriter.Write8(0x0C); }
public void WriteASS(int display, int index) {
mWriter.Write8(0x0D);
mWriter.Write8(0x04); // unused (skipped over by TSpcInterp)
mWriter.WriteS32(display);
mWriter.WriteS32(index);
}
public void WriteEQ() { mWriter.Write8(0x0E); }
public void WriteNE() { mWriter.Write8(0x0F); }
public void WriteGT() { mWriter.Write8(0x10); }
public void WriteLT() { mWriter.Write8(0x11); }
public void WriteGE() { mWriter.Write8(0x12); }
public void WriteLE() { mWriter.Write8(0x13); }
public void WriteNEG() { mWriter.Write8(0x14); }
public void WriteNOT() { mWriter.Write8(0x15); }
public void WriteAND() { mWriter.Write8(0x16); }
public void WriteOR() { mWriter.Write8(0x17); }
public void WriteBAND() { mWriter.Write8(0x18); }
public void WriteBOR() { mWriter.Write8(0x19); }
public void WriteSHL() { mWriter.Write8(0x1A); }
public void WriteSHR() { mWriter.Write8(0x1B); }
public sunPoint WriteCALL(int count) {
mWriter.Write8(0x1C);
sunPoint point = OpenPoint();
mWriter.Write32(0); // dummy
mWriter.WriteS32(count);
return point;
}
public void WriteCALL(sunPoint point, int count) {
mWriter.Write8(0x1C);
mWriter.Write32(point.Offset);
mWriter.WriteS32(count);
}
public void WriteFUNC(int index, int count) {
mWriter.Write8(0x1D);
mWriter.WriteS32(index);
mWriter.WriteS32(count);
}
public void WriteMKFR(int count) {
mWriter.Write8(0x1E);
mWriter.WriteS32(count);
}
public void WriteMKDS(int display) {
mWriter.Write8(0x1F);
mWriter.WriteS32(display);
}
public void WriteRET() { mWriter.Write8(0x20); }
public void WriteRET0() { mWriter.Write8(0x21); }
public sunPoint WriteJNE() {
mWriter.Write8(0x22);
sunPoint point = OpenPoint();
mWriter.Write32(0); // dummy
return point;
}
public sunPoint WriteJMP() {
mWriter.Write8(0x23);
sunPoint point = OpenPoint();
mWriter.Write32(0); // dummy
return point;
}
public void WriteJNE(sunPoint point) {
mWriter.Write8(0x22);
mWriter.Write32(point.Offset);
}
public void WriteJMP(sunPoint point) {
mWriter.Write8(0x23);
mWriter.Write32(point.Offset);
}
public void WritePOP() { mWriter.Write8(0x24); }
public void WriteINT0() { mWriter.Write8(0x25); }
public void WriteINT1() { mWriter.Write8(0x26); }
public void WriteEND() { mWriter.Write8(0x27); }
}
struct sunPoint {
readonly uint mOffset;
public uint Offset { get { return mOffset; } }
public sunPoint(uint offset) {
mOffset = offset;
}
}
}