Added code so far.
This commit is contained in:
parent
12301380a2
commit
4f1e820006
22 changed files with 3397 additions and 0 deletions
127
ast/nodes.cs
Normal file
127
ast/nodes.cs
Normal file
|
@ -0,0 +1,127 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace arookas
|
||||
{
|
||||
public class sunSourceLocation
|
||||
{
|
||||
public string File { get; private set; }
|
||||
public int Line { get; private set; }
|
||||
public int Column { get; private set; }
|
||||
|
||||
public sunSourceLocation(string file, int line, int column)
|
||||
{
|
||||
File = file;
|
||||
Line = line;
|
||||
Column = column;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("\"{0}\", ({1},{2})", File, Line, Column);
|
||||
}
|
||||
}
|
||||
|
||||
class sunNode : IEnumerable<sunNode>
|
||||
{
|
||||
List<sunNode> children;
|
||||
|
||||
public sunNode Parent { get; private set; }
|
||||
public sunSourceLocation Location { get; private set; }
|
||||
|
||||
public int Count { get { return children.Count; } }
|
||||
public sunNode this[int index] { get { return index >= 0 && index < Count ? children[index] : null; } }
|
||||
|
||||
public bool IsRoot { get { return Parent == null; } }
|
||||
public bool IsBranch { get { return Count > 0; } }
|
||||
public bool IsLeaf { get { return Count < 1; } }
|
||||
|
||||
public sunNode(sunSourceLocation location)
|
||||
{
|
||||
children = new List<sunNode>(5);
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void Add(sunNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException("node");
|
||||
}
|
||||
if (node.Parent != null)
|
||||
{
|
||||
node.Parent.Remove(node);
|
||||
}
|
||||
node.Parent = this;
|
||||
children.Add(node);
|
||||
}
|
||||
public void Remove(sunNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException("node");
|
||||
}
|
||||
if (node.Parent == this)
|
||||
{
|
||||
children.Remove(node);
|
||||
node.Parent = null;
|
||||
}
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var child in this)
|
||||
{
|
||||
child.Parent = null;
|
||||
}
|
||||
children.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.
|
||||
foreach (var child in this)
|
||||
{
|
||||
child.Compile(context);
|
||||
}
|
||||
}
|
||||
protected bool TryCompile(sunNode node, sunContext context)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
node.Compile(context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerator<sunNode> GetEnumerator() { return children.GetEnumerator(); }
|
||||
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||
}
|
||||
|
||||
abstract class sunToken<TValue> : sunNode
|
||||
{
|
||||
public TValue Value { get; private set; }
|
||||
|
||||
protected sunToken(sunSourceLocation location, string token)
|
||||
: base(location)
|
||||
{
|
||||
Value = ParseValue(token);
|
||||
}
|
||||
|
||||
protected abstract TValue ParseValue(string token);
|
||||
}
|
||||
|
||||
abstract class sunRawToken : sunToken<string>
|
||||
{
|
||||
protected sunRawToken(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override string ParseValue(string token) { return token; }
|
||||
}
|
||||
}
|
122
ast/nodes.expressions.cs
Normal file
122
ast/nodes.expressions.cs
Normal file
|
@ -0,0 +1,122 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace arookas
|
||||
{
|
||||
class sunExpression : sunNode
|
||||
{
|
||||
public sunExpression(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
Stack<sunOperator> operatorStack = new Stack<sunOperator>(32);
|
||||
AnalyzeExpression(context, this, operatorStack);
|
||||
}
|
||||
|
||||
void AnalyzeExpression(sunContext context, 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;
|
||||
foreach (var node in expression)
|
||||
{
|
||||
if (node is sunOperand)
|
||||
{
|
||||
var operand = node as sunOperand;
|
||||
|
||||
// term
|
||||
var term = operand.Term;
|
||||
if (term is sunExpression)
|
||||
{
|
||||
AnalyzeExpression(context, term as sunExpression, operatorStack);
|
||||
}
|
||||
else
|
||||
{
|
||||
term.Compile(context);
|
||||
}
|
||||
var unaryOperators = operand.UnaryOperators;
|
||||
if (unaryOperators != null)
|
||||
{
|
||||
unaryOperators.Compile(context);
|
||||
}
|
||||
}
|
||||
else if (node is sunOperator)
|
||||
{
|
||||
var operatorNode = node as sunOperator;
|
||||
while (operatorStack.Count > stackCount &&
|
||||
(operatorNode.IsLeftAssociative && operatorNode.Precedence <= operatorStack.Peek().Precedence) ||
|
||||
(operatorNode.IsRightAssociative && operatorNode.Precedence < operatorStack.Peek().Precedence))
|
||||
{
|
||||
operatorStack.Pop().Compile(context);
|
||||
}
|
||||
operatorStack.Push(operatorNode);
|
||||
}
|
||||
}
|
||||
while (operatorStack.Count > stackCount)
|
||||
{
|
||||
operatorStack.Pop().Compile(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunOperand : sunNode
|
||||
{
|
||||
public sunNode UnaryOperators { get { return Count > 1 ? this[0] : null; } }
|
||||
public sunNode Term { get { return this[Count - 1]; } }
|
||||
|
||||
public sunOperand(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// operands are compiled in sunExpression.Compile
|
||||
}
|
||||
|
||||
class sunUnaryOperatorList : sunNode
|
||||
{
|
||||
public sunUnaryOperatorList(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
foreach (var child in this.Reverse())
|
||||
{
|
||||
// compile unary operators in reverse order
|
||||
child.Compile(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunTernaryOperator : sunNode
|
||||
{
|
||||
public sunExpression Condition { get { return this[0] as sunExpression; } }
|
||||
public sunExpression TrueBody { get { return this[1] as sunExpression; } }
|
||||
public sunExpression FalseBody { get { return this[2] as sunExpression; } }
|
||||
|
||||
public sunTernaryOperator(sunSourceLocation node)
|
||||
: base(node)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
Condition.Compile(context);
|
||||
var falsePrologue = context.Text.GotoIfZero();
|
||||
TrueBody.Compile(context);
|
||||
var trueEpilogue = context.Text.Goto();
|
||||
context.Text.ClosePoint(falsePrologue);
|
||||
FalseBody.Compile(context);
|
||||
context.Text.ClosePoint(trueEpilogue);
|
||||
}
|
||||
}
|
||||
}
|
224
ast/nodes.flow.cs
Normal file
224
ast/nodes.flow.cs
Normal file
|
@ -0,0 +1,224 @@
|
|||
using PerCederberg.Grammatica.Runtime;
|
||||
using System.Linq;
|
||||
|
||||
namespace arookas
|
||||
{
|
||||
class sunIf : sunNode
|
||||
{
|
||||
public sunExpression Condition { get { return this[0] as sunExpression; } }
|
||||
public sunNode TrueBody { get { return this[1]; } }
|
||||
public sunNode FalseBody { get { return this[2]; } }
|
||||
|
||||
public sunIf(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
Condition.Compile(context);
|
||||
var trueBodyEpilogue = context.Text.GotoIfZero();
|
||||
TrueBody.Compile(context);
|
||||
var falseBody = FalseBody;
|
||||
if (falseBody != null)
|
||||
{
|
||||
var falseBodyEpilogue = context.Text.Goto();
|
||||
context.Text.ClosePoint(trueBodyEpilogue);
|
||||
falseBody.Compile(context);
|
||||
context.Text.ClosePoint(falseBodyEpilogue);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Text.ClosePoint(trueBodyEpilogue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class sunLoop : sunNode
|
||||
{
|
||||
public bool IsNamed { get { return NameLabel != null; } }
|
||||
public sunNameLabel NameLabel { get { return this[0] as sunNameLabel; } }
|
||||
|
||||
protected sunLoop(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class sunWhile : sunLoop
|
||||
{
|
||||
public sunExpression Condition { get { return this[Count - 2] as sunExpression; } }
|
||||
public sunNode Body { get { return this[Count - 1]; } }
|
||||
|
||||
public sunWhile(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Loops.Push(IsNamed ? NameLabel.Label.Value : null);
|
||||
var bodyPrologue = context.Text.OpenPoint();
|
||||
var continuePoint = context.Text.OpenPoint();
|
||||
Condition.Compile(context);
|
||||
var bodyEpilogue = context.Text.GotoIfZero();
|
||||
Body.Compile(context);
|
||||
context.Text.Goto(bodyPrologue);
|
||||
context.Text.ClosePoint(bodyEpilogue);
|
||||
var breakPoint = context.Text.OpenPoint();
|
||||
context.Loops.Pop(context, breakPoint, continuePoint);
|
||||
}
|
||||
}
|
||||
|
||||
class sunDo : sunLoop
|
||||
{
|
||||
public sunNode Body { get { return this[Count - 2]; } }
|
||||
public sunExpression Condition { get { return this[Count - 1] as sunExpression; } }
|
||||
|
||||
public sunDo(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Loops.Push(IsNamed ? NameLabel.Label.Value : null);
|
||||
var bodyPrologue = context.Text.OpenPoint();
|
||||
Body.Compile(context);
|
||||
var continuePoint = context.Text.OpenPoint();
|
||||
Condition.Compile(context);
|
||||
var bodyEpilogue = context.Text.GotoIfZero();
|
||||
context.Text.Goto(bodyPrologue);
|
||||
context.Text.ClosePoint(bodyEpilogue);
|
||||
var breakPoint = context.Text.OpenPoint();
|
||||
context.Loops.Pop(context, breakPoint, continuePoint);
|
||||
}
|
||||
}
|
||||
|
||||
class sunFor : sunLoop
|
||||
{
|
||||
public sunForDeclaration Declaration { get { return this.FirstOrDefault(i => i is sunForDeclaration) as sunForDeclaration; } }
|
||||
public sunForCondition Condition { get { return this.FirstOrDefault(i => i is sunForCondition) as sunForCondition; } }
|
||||
public sunForIteration Iteration { get { return this.FirstOrDefault(i => i is sunForIteration) as sunForIteration; } }
|
||||
public sunNode Body { get { return this[Count - 1]; } }
|
||||
|
||||
public sunFor(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Scopes.Push();
|
||||
context.Loops.Push(IsNamed ? NameLabel.Label.Value : null);
|
||||
TryCompile(Declaration, context);
|
||||
var bodyPrologue = context.Text.OpenPoint();
|
||||
TryCompile(Condition, context);
|
||||
var bodyEpilogue = context.Text.GotoIfZero();
|
||||
Body.Compile(context);
|
||||
var continuePoint = context.Text.OpenPoint();
|
||||
TryCompile(Iteration, context);
|
||||
context.Text.Goto(bodyPrologue);
|
||||
context.Text.ClosePoint(bodyEpilogue);
|
||||
var breakPoint = context.Text.OpenPoint();
|
||||
context.Loops.Pop(context, breakPoint, continuePoint);
|
||||
context.Scopes.Pop();
|
||||
}
|
||||
}
|
||||
class sunForDeclaration : sunNode
|
||||
{
|
||||
public sunForDeclaration(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
class sunForCondition : sunNode
|
||||
{
|
||||
public sunForCondition(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
class sunForIteration : sunNode
|
||||
{
|
||||
public sunForIteration(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class sunReturn : sunNode
|
||||
{
|
||||
public sunExpression Expression { get { return this[0] as sunExpression; } }
|
||||
|
||||
public sunReturn(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var expression = Expression;
|
||||
if (expression != null)
|
||||
{
|
||||
expression.Compile(context);
|
||||
context.Text.ReturnValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Text.ReturnVoid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunBreak : sunNode
|
||||
{
|
||||
public bool IsNamed { get { return Count > 0; } }
|
||||
public sunIdentifier NameLabel { get { return this[0] as sunIdentifier; } }
|
||||
|
||||
public sunBreak(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var point = context.Text.Goto();
|
||||
if (!context.Loops.AddBreak(point, IsNamed ? NameLabel.Value : null))
|
||||
{
|
||||
throw new sunBreakException(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunContinue : sunNode
|
||||
{
|
||||
public bool IsNamed { get { return Count > 0; } }
|
||||
public sunIdentifier NameLabel { get { return this[0] as sunIdentifier; } }
|
||||
|
||||
public sunContinue(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var point = context.Text.Goto();
|
||||
if (!context.Loops.AddContinue(point, IsNamed ? NameLabel.Value : null))
|
||||
{
|
||||
throw new sunContinueException(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
ast/nodes.functions.cs
Normal file
95
ast/nodes.functions.cs
Normal file
|
@ -0,0 +1,95 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace arookas
|
||||
{
|
||||
class sunBuiltinDeclaration : sunNode
|
||||
{
|
||||
public sunIdentifier Builtin { get { return this[0] as sunIdentifier; } }
|
||||
public sunParameterList Parameters { get { return this[1] as sunParameterList; } }
|
||||
|
||||
public sunBuiltinDeclaration(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.DeclareBuiltin(this);
|
||||
}
|
||||
}
|
||||
|
||||
class sunFunctionDefinition : sunNode
|
||||
{
|
||||
public sunIdentifier Function { get { return this[0] as sunIdentifier; } }
|
||||
public sunParameterList Parameters { get { return this[1] as sunParameterList; } }
|
||||
public sunNode Body { get { return this[2]; } }
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
class sunFunctionCall : sunNode
|
||||
{
|
||||
public sunIdentifier Function { get { return this[0] as sunIdentifier; } }
|
||||
public sunNode Arguments { get { return this[1] as sunNode; } }
|
||||
|
||||
bool IsStatement { get { return !(Parent is sunOperand); } }
|
||||
|
||||
public sunFunctionCall(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var callableInfo = context.ResolveCallable(this);
|
||||
if (!callableInfo.Parameters.ValidateArgumentCount(Arguments.Count))
|
||||
{
|
||||
throw new sunArgumentCountException(this, callableInfo);
|
||||
}
|
||||
Arguments.Compile(context);
|
||||
callableInfo.OpenCallSite(context, Arguments.Count);
|
||||
if (IsStatement)
|
||||
{
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunParameterList : sunNode
|
||||
{
|
||||
public IEnumerable<sunIdentifier> Parameters { get { return this.OfType<sunIdentifier>(); } }
|
||||
public bool IsVariadic { get { return Count > 0 && this[Count - 1] is sunEllipsis; } }
|
||||
public sunParameterInfo ParameterInfo { get { return new sunParameterInfo(Parameters, IsVariadic); } }
|
||||
|
||||
public sunParameterList(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
int count = this.Count(i => i is sunEllipsis);
|
||||
if (count > 1 || (count > 0 && !(this[Count - 1] is sunEllipsis)))
|
||||
{
|
||||
throw new sunVariadicParameterListException(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunEllipsis : sunNode
|
||||
{
|
||||
public sunEllipsis(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
201
ast/nodes.literals.cs
Normal file
201
ast/nodes.literals.cs
Normal file
|
@ -0,0 +1,201 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace arookas
|
||||
{
|
||||
class sunIntLiteral : sunToken<int> // base-10 integer
|
||||
{
|
||||
public sunIntLiteral(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override int ParseValue(string token) { return Int32.Parse(token); }
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Text.PushInt(Value);
|
||||
}
|
||||
}
|
||||
|
||||
class sunHexLiteral : sunIntLiteral // base-16 integer
|
||||
{
|
||||
public sunHexLiteral(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override int ParseValue(string token)
|
||||
{
|
||||
// because .NET's hex parsing is gay and doesn't support
|
||||
// leading signs, manually detect negative literals
|
||||
var neg = (token[0] == '-');
|
||||
var trim = neg ? 3 : 2;
|
||||
var digits = token.Substring(trim); // trim the '0x' prefix before parsing
|
||||
var value = Int32.Parse(token.Substring(2), NumberStyles.AllowHexSpecifier);
|
||||
if (neg)
|
||||
{
|
||||
value = -value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
class sunFloatLiteral : sunToken<float>
|
||||
{
|
||||
public sunFloatLiteral(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override float ParseValue(string image) { return Single.Parse(image); }
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Text.PushFloat(Value);
|
||||
}
|
||||
}
|
||||
|
||||
class sunStringLiteral : sunToken<string>
|
||||
{
|
||||
public sunStringLiteral(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override string ParseValue(string image) { return UnescapeString(image.Substring(1, image.Length - 2)); } // remove enclosing quotes
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Text.PushData(context.DataTable.Add(Value));
|
||||
}
|
||||
|
||||
// string unescaping utility
|
||||
string UnescapeString(string value)
|
||||
{
|
||||
// based on Hans Passant's code
|
||||
StringBuilder sb = new StringBuilder(value.Length);
|
||||
for (int i = 0; i < value.Length;)
|
||||
{
|
||||
int j = value.IndexOf('\\', i);
|
||||
if (j < 0 || j >= value.Length - 1)
|
||||
{
|
||||
j = value.Length;
|
||||
}
|
||||
sb.Append(value, i, j - i);
|
||||
if (j >= value.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
switch (value[j + 1])
|
||||
{
|
||||
case '\'': sb.Append('\''); break;
|
||||
case '"': sb.Append('"'); break;
|
||||
case '\\': sb.Append('\\'); break;
|
||||
case '0': sb.Append('\0'); break;
|
||||
case 'a': sb.Append('\a'); break;
|
||||
case 'b': sb.Append('\b'); break;
|
||||
case 'f': sb.Append('\f'); break;
|
||||
case 'n': sb.Append('n'); break;
|
||||
case 't': sb.Append('\t'); break;
|
||||
case 'v': sb.Append('\v'); break;
|
||||
case 'x': sb.Append(UnescapeHex(value, j + 2, out i)); continue;
|
||||
case 'u': sb.Append(UnescapeUnicodeCodeUnit(value, j + 2, out i)); continue;
|
||||
case 'U': sb.Append(UnescapeUnicodeSurrogatePair(value, j + 2, out i)); continue;
|
||||
default: throw new sunEscapeSequenceException(this);
|
||||
}
|
||||
i = j + 2;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
char UnescapeHex(string value, int start, out int end)
|
||||
{
|
||||
if (start > value.Length)
|
||||
{
|
||||
throw new sunEscapeSequenceException(this); // we need at least one digit
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(4);
|
||||
int digits = 0;
|
||||
while (digits < 4 && start < value.Length && IsHexDigit(value[start]))
|
||||
{
|
||||
sb.Append(value[start]);
|
||||
++digits;
|
||||
++start;
|
||||
}
|
||||
end = start;
|
||||
return (char)Int32.Parse(sb.ToString(), NumberStyles.AllowHexSpecifier);
|
||||
}
|
||||
char UnescapeUnicodeCodeUnit(string value, int start, out int end)
|
||||
{
|
||||
if (start >= value.Length - 4)
|
||||
{
|
||||
throw new sunEscapeSequenceException(this); // we need four digits
|
||||
}
|
||||
end = start + 4;
|
||||
return (char)Int32.Parse(value.Substring(start, 4), NumberStyles.AllowHexSpecifier);
|
||||
}
|
||||
string UnescapeUnicodeSurrogatePair(string value, int start, out int end)
|
||||
{
|
||||
if (start >= value.Length - 8)
|
||||
{
|
||||
throw new sunEscapeSequenceException(this); // we need eight digits
|
||||
}
|
||||
char high = (char)Int32.Parse(value.Substring(start, 4), NumberStyles.AllowHexSpecifier);
|
||||
char low = (char)Int32.Parse(value.Substring(start + 4, 4), NumberStyles.AllowHexSpecifier);
|
||||
if (!Char.IsHighSurrogate(high) || !Char.IsLowSurrogate(low))
|
||||
{
|
||||
throw new sunEscapeSequenceException(this); // characters are not a surrogate pair
|
||||
}
|
||||
end = start + 8;
|
||||
return String.Concat(high, low);
|
||||
}
|
||||
static bool IsHexDigit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= 'a' && c <= 'f');
|
||||
}
|
||||
}
|
||||
|
||||
class sunIdentifier : sunRawToken
|
||||
{
|
||||
public sunIdentifier(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
// make sure it is a valid identifier name (i.e. not a keyword)
|
||||
if (sunParser.IsKeyword(Value))
|
||||
{
|
||||
throw new sunIdentifierException(this);
|
||||
}
|
||||
}
|
||||
|
||||
// identifiers are compiled on a per-context basis (i.e. at a higher level)
|
||||
}
|
||||
|
||||
class sunTrue : sunIntLiteral
|
||||
{
|
||||
public sunTrue(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override int ParseValue(string token) { return 1; }
|
||||
}
|
||||
|
||||
class sunFalse : sunIntLiteral
|
||||
{
|
||||
public sunFalse(sunSourceLocation location, string token)
|
||||
: base(location, token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override int ParseValue(string token) { return 0; }
|
||||
}
|
||||
}
|
453
ast/nodes.operators.cs
Normal file
453
ast/nodes.operators.cs
Normal file
|
@ -0,0 +1,453 @@
|
|||
using PerCederberg.Grammatica.Runtime;
|
||||
|
||||
namespace arookas
|
||||
{
|
||||
enum Associativity
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
abstract class sunOperator : sunNode
|
||||
{
|
||||
public virtual Associativity Associativity { get { return Associativity.Left; } }
|
||||
public abstract int Precedence { get; }
|
||||
|
||||
public bool IsLeftAssociative { get { return Associativity == Associativity.Left; } }
|
||||
public bool IsRightAssociative { get { return Associativity == Associativity.Right; } }
|
||||
|
||||
protected sunOperator(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// precedence 0
|
||||
class sunLogOR : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 0; } }
|
||||
|
||||
public sunLogOR(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.LogOR(); }
|
||||
}
|
||||
|
||||
// precedence 1
|
||||
class sunLogAND : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 1; } }
|
||||
|
||||
public sunLogAND(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.LogAND(); }
|
||||
}
|
||||
|
||||
// precedence 2
|
||||
class sunBitOR : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 2; } }
|
||||
|
||||
public sunBitOR(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.BitOR(); }
|
||||
}
|
||||
|
||||
// precedence 3
|
||||
class sunBitAND : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 3; } }
|
||||
|
||||
public sunBitAND(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.BitAND(); }
|
||||
}
|
||||
|
||||
// precedence 4
|
||||
class sunEq : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 4; } }
|
||||
|
||||
public sunEq(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Eq(); }
|
||||
}
|
||||
|
||||
class sunNtEq : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 4; } }
|
||||
|
||||
public sunNtEq(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.NtEq(); }
|
||||
}
|
||||
|
||||
// precedence 5
|
||||
class sunLt : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 5; } }
|
||||
|
||||
public sunLt(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Lt(); }
|
||||
}
|
||||
|
||||
class sunLtEq : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 5; } }
|
||||
|
||||
public sunLtEq(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.LtEq(); }
|
||||
}
|
||||
|
||||
class sunGt : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 5; } }
|
||||
|
||||
public sunGt(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Gt(); }
|
||||
}
|
||||
|
||||
class sunGtEq : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 5; } }
|
||||
|
||||
public sunGtEq(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.GtEq(); }
|
||||
}
|
||||
|
||||
// precedence 6
|
||||
class sunBitLsh : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 6; } }
|
||||
|
||||
public sunBitLsh(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.ShL(); }
|
||||
}
|
||||
|
||||
class sunBitRsh : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 6; } }
|
||||
|
||||
public sunBitRsh(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.ShR(); }
|
||||
}
|
||||
|
||||
// precedence 7
|
||||
class sunAdd : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 7; } }
|
||||
|
||||
public sunAdd(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Add(); }
|
||||
}
|
||||
|
||||
class sunSub : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 7; } }
|
||||
|
||||
public sunSub(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Sub(); }
|
||||
}
|
||||
|
||||
// precedence 8
|
||||
class sunMul : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 8; } }
|
||||
|
||||
public sunMul(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Mul(); }
|
||||
}
|
||||
|
||||
class sunDiv : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 8; } }
|
||||
|
||||
public sunDiv(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Div(); }
|
||||
}
|
||||
|
||||
class sunMod : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 8; } }
|
||||
|
||||
public sunMod(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Mod(); }
|
||||
}
|
||||
|
||||
// precedence 9
|
||||
class sunLogNOT : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 9; } }
|
||||
|
||||
public sunLogNOT(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.LogNOT(); }
|
||||
}
|
||||
class sunNeg : sunOperator
|
||||
{
|
||||
public override int Precedence { get { return 9; } }
|
||||
|
||||
public sunNeg(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.Neg(); }
|
||||
}
|
||||
|
||||
// assignment operators
|
||||
class sunAssign : sunOperator
|
||||
{
|
||||
public override Associativity Associativity { get { return Associativity.Right; } }
|
||||
public override int Precedence { get { return -1; } }
|
||||
|
||||
public sunAssign(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
expression.Compile(context);
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignAdd : sunAssign
|
||||
{
|
||||
public sunAssignAdd(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.Add();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignSub : sunAssign
|
||||
{
|
||||
public sunAssignSub(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.Sub();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignMul : sunAssign
|
||||
{
|
||||
public sunAssignMul(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.Mul();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignDiv : sunAssign
|
||||
{
|
||||
public sunAssignDiv(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.Div();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignMod : sunAssign
|
||||
{
|
||||
public sunAssignMod(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.Mod();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignBitAND : sunAssign
|
||||
{
|
||||
public sunAssignBitAND(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.BitAND();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignBitOR : sunAssign
|
||||
{
|
||||
public sunAssignBitOR(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.BitOR();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignBitLsh : sunAssign
|
||||
{
|
||||
public sunAssignBitLsh(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.ShL();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
class sunAssignBitRsh : sunAssign
|
||||
{
|
||||
public sunAssignBitRsh(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context, sunVariableInfo variableInfo, sunExpression expression)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
expression.Compile(context);
|
||||
context.Text.ShR();
|
||||
context.Text.StoreVariable(variableInfo);
|
||||
}
|
||||
}
|
||||
}
|
50
ast/nodes.statements.cs
Normal file
50
ast/nodes.statements.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
namespace arookas
|
||||
{
|
||||
class sunStatementBlock : sunNode
|
||||
{
|
||||
public sunStatementBlock(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
context.Scopes.Push();
|
||||
base.Compile(context);
|
||||
context.Scopes.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
class sunImport : sunNode
|
||||
{
|
||||
public sunStringLiteral ImportFile { get { return this[0] as sunStringLiteral; } }
|
||||
|
||||
public sunImport(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var file = context.Imports.ResolveImport(this);
|
||||
if (file == null)
|
||||
{
|
||||
return; // the file has already been imported
|
||||
}
|
||||
context.Compile(file);
|
||||
}
|
||||
}
|
||||
|
||||
class sunNameLabel : sunNode
|
||||
{
|
||||
public sunIdentifier Label { get { return this[0] as sunIdentifier; } }
|
||||
|
||||
public sunNameLabel(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
155
ast/nodes.system.cs
Normal file
155
ast/nodes.system.cs
Normal file
|
@ -0,0 +1,155 @@
|
|||
namespace arookas
|
||||
{
|
||||
class sunYield : sunNode
|
||||
{
|
||||
public sunYield(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("yield");
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 0);
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
class sunExit : sunNode
|
||||
{
|
||||
public sunExit(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("exit");
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 0);
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
class sunDump : sunNode
|
||||
{
|
||||
public sunDump(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("dump");
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 0);
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
class sunLock : sunNode
|
||||
{
|
||||
public sunLock(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("lock");
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 0);
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
class sunUnlock : sunNode
|
||||
{
|
||||
public sunUnlock(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("unlock");
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 0);
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
class sunIntCast : sunNode
|
||||
{
|
||||
public sunExpression Argument { get { return this[0] as sunExpression; } }
|
||||
|
||||
public sunIntCast(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.DeclareSystemBuiltin("int", false, "x");
|
||||
Argument.Compile(context);
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class sunFloatCast : sunNode
|
||||
{
|
||||
public sunExpression Argument { get { return this[0] as sunExpression; } }
|
||||
|
||||
public sunFloatCast(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("float");
|
||||
Argument.Compile(context);
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class sunTypeofCast : sunNode
|
||||
{
|
||||
public sunExpression Argument { get { return this[0] as sunExpression; } }
|
||||
|
||||
public sunTypeofCast(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("typeof");
|
||||
Argument.Compile(context);
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class sunPrint : sunNode
|
||||
{
|
||||
public sunNode ArgumentList { get { return this[0]; } }
|
||||
|
||||
public sunPrint(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var builtinInfo = context.ResolveSystemBuiltin("print");
|
||||
ArgumentList.Compile(context);
|
||||
context.Text.CallBuiltin(builtinInfo.Index, ArgumentList.Count);
|
||||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
}
|
96
ast/nodes.variables.cs
Normal file
96
ast/nodes.variables.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
namespace arookas
|
||||
{
|
||||
class sunVariableReference : sunNode
|
||||
{
|
||||
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
||||
|
||||
public sunVariableReference(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
sunVariableInfo variableInfo;
|
||||
sunConstInfo constInfo;
|
||||
context.ResolveVariableOrConstant(Variable, out variableInfo, out constInfo);
|
||||
if (variableInfo != null)
|
||||
{
|
||||
context.Text.PushVariable(variableInfo);
|
||||
}
|
||||
if (constInfo != null)
|
||||
{
|
||||
constInfo.Expression.Compile(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sunVariableDeclaration : sunNode
|
||||
{
|
||||
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
||||
|
||||
public sunVariableDeclaration(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var variableInfo = context.DeclareVariable(Variable);
|
||||
context.Text.DeclareLocal(1);
|
||||
}
|
||||
}
|
||||
|
||||
class sunVariableDefinition : sunVariableAssignment
|
||||
{
|
||||
public sunVariableDefinition(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var variableInfo = context.DeclareVariable(Variable);
|
||||
context.Text.DeclareLocal(1);
|
||||
base.Compile(context);
|
||||
}
|
||||
}
|
||||
|
||||
class sunVariableAssignment : sunVariableDeclaration
|
||||
{
|
||||
public sunAssign Operator { get { return this[1] as sunAssign; } }
|
||||
public sunExpression Expression { get { return this[2] as sunExpression; } }
|
||||
|
||||
public sunVariableAssignment(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var variableInfo = context.ResolveVariable(Variable);
|
||||
Operator.Compile(context, variableInfo, Expression);
|
||||
}
|
||||
}
|
||||
|
||||
class sunConstDefinition : sunNode
|
||||
{
|
||||
public sunIdentifier Constant { get { return this[0] as sunIdentifier; } }
|
||||
public sunExpression Expression { get { return this[2] as sunExpression; } }
|
||||
|
||||
public sunConstDefinition(sunSourceLocation location)
|
||||
: base(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Compile(sunContext context)
|
||||
{
|
||||
var constInfo = context.DeclareConstant(Constant, Expression);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue