diff --git a/ssc/ast/nodes.cs b/ssc/ast/nodes.cs index 7e15616..d354957 100644 --- a/ssc/ast/nodes.cs +++ b/ssc/ast/nodes.cs @@ -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 GetEnumerator() { return mChildren.GetEnumerator(); } diff --git a/ssc/ast/nodes.expressions.cs b/ssc/ast/nodes.expressions.cs index f992a49..e31e452 100644 --- a/ssc/ast/nodes.expressions.cs +++ b/ssc/ast/nodes.expressions.cs @@ -12,15 +12,15 @@ namespace arookas { public sunExpression(sunSourceLocation location) : base(location) { } - public override void Compile(sunContext context) { - Stack operatorStack = new Stack(32); - CompileExpression(context, this, operatorStack); + public override void Compile(sunCompiler compiler) { + var operatorStack = new Stack(32); + CompileExpression(compiler, this, operatorStack); } public sunExpressionFlags Analyze(sunContext context) { return AnalyzeExpression(context, this); } - static void CompileExpression(sunContext context, sunExpression expression, Stack operatorStack) { + static void CompileExpression(sunCompiler compiler, sunExpression expression, Stack 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()) { 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); } } } diff --git a/ssc/ast/nodes.flow.cs b/ssc/ast/nodes.flow.cs index 3ac4541..c9b4f6f 100644 --- a/ssc/ast/nodes.flow.cs +++ b/ssc/ast/nodes.flow.cs @@ -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); } } diff --git a/ssc/ast/nodes.functions.cs b/ssc/ast/nodes.functions.cs index d063d2e..2bb88ad 100644 --- a/ssc/ast/nodes.functions.cs +++ b/ssc/ast/nodes.functions.cs @@ -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(); } } diff --git a/ssc/ast/nodes.literals.cs b/ssc/ast/nodes.literals.cs index 46ea074..18fd63f 100644 --- a/ssc/ast/nodes.literals.cs +++ b/ssc/ast/nodes.literals.cs @@ -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 diff --git a/ssc/ast/nodes.operators.cs b/ssc/ast/nodes.operators.cs index 3acdd10..568c69d 100644 --- a/ssc/ast/nodes.operators.cs +++ b/ssc/ast/nodes.operators.cs @@ -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); } } } diff --git a/ssc/ast/nodes.statements.cs b/ssc/ast/nodes.statements.cs index 4e8f871..475a252 100644 --- a/ssc/ast/nodes.statements.cs +++ b/ssc/ast/nodes.statements.cs @@ -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); } } } diff --git a/ssc/ast/nodes.system.cs b/ssc/ast/nodes.system.cs index 7b32e5b..3f1c1be 100644 --- a/ssc/ast/nodes.system.cs +++ b/ssc/ast/nodes.system.cs @@ -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); } } } diff --git a/ssc/ast/nodes.variables.cs b/ssc/ast/nodes.variables.cs index 30d39a8..7afcd8f 100644 --- a/ssc/ast/nodes.variables.cs +++ b/ssc/ast/nodes.variables.cs @@ -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); } } } diff --git a/ssc/binary.cs b/ssc/binary.cs new file mode 100644 index 0000000..fe1a270 --- /dev/null +++ b/ssc/binary.cs @@ -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; + } + } +} diff --git a/ssc/compiler.cs b/ssc/compiler.cs index 4828c47..58de178 100644 --- a/ssc/compiler.cs +++ b/ssc/compiler.cs @@ -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 { diff --git a/ssc/context.cs b/ssc/context.cs index 9f7d1aa..fbd6efa 100644 --- a/ssc/context.cs +++ b/ssc/context.cs @@ -7,17 +7,12 @@ using System.Text; namespace arookas { class sunContext { - bool mOpen; - aBinaryWriter mWriter; - uint mTextOffset, mDataOffset, mSymbolOffset; Stack 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(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); - } } } diff --git a/ssc/data table.cs b/ssc/data table.cs index 5da6338..d2d91b0 100644 --- a/ssc/data table.cs +++ b/ssc/data table.cs @@ -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 GetEnumerator() { return data.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } diff --git a/ssc/loop stack.cs b/ssc/loop stack.cs index 6e5d755..d65c7ce 100644 --- a/ssc/loop stack.cs +++ b/ssc/loop stack.cs @@ -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); } } } diff --git a/ssc/symbol table.cs b/ssc/symbol table.cs index eb724ff..4f34dac 100644 --- a/ssc/symbol table.cs +++ b/ssc/symbol table.cs @@ -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 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(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(); } diff --git a/ssc/writer.cs b/ssc/writer.cs deleted file mode 100644 index 96670fb..0000000 --- a/ssc/writer.cs +++ /dev/null @@ -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; - } - } -}