Added expression analysis.
Also gave the AST cast nodes a base class while I was at it.
This commit is contained in:
parent
6be1779781
commit
54bd3618e3
5 changed files with 108 additions and 28 deletions
|
@ -1,9 +1,14 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace arookas {
|
||||
class sunExpression : sunNode {
|
||||
interface sunTerm {
|
||||
sunExpressionFlags GetExpressionFlags(sunContext context);
|
||||
}
|
||||
|
||||
class sunExpression : sunNode, sunTerm {
|
||||
public sunExpression(sunSourceLocation location)
|
||||
: base(location) { }
|
||||
|
||||
|
@ -11,8 +16,11 @@ namespace arookas {
|
|||
Stack<sunOperator> operatorStack = new Stack<sunOperator>(32);
|
||||
CompileExpression(context, this, operatorStack);
|
||||
}
|
||||
public sunExpressionFlags Analyze(sunContext context) {
|
||||
return AnalyzeExpression(context, this);
|
||||
}
|
||||
|
||||
void CompileExpression(sunContext context, sunExpression expression, Stack<sunOperator> operatorStack) {
|
||||
static void CompileExpression(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;
|
||||
|
@ -47,6 +55,35 @@ namespace arookas {
|
|||
operatorStack.Pop().Compile(context);
|
||||
}
|
||||
}
|
||||
static sunExpressionFlags AnalyzeExpression(sunContext context, sunExpression expression) {
|
||||
sunExpressionFlags flags = sunExpressionFlags.None;
|
||||
foreach (var operand in expression.OfType<sunOperand>()) {
|
||||
var term = operand.Term as sunTerm;
|
||||
if (term != null) {
|
||||
flags |= term.GetExpressionFlags(context);
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return Analyze(context);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum sunExpressionFlags {
|
||||
// contents
|
||||
None = 0,
|
||||
Literals = 1,
|
||||
Variables = 2,
|
||||
Augments = 4,
|
||||
Casts = 8,
|
||||
Calls = 16,
|
||||
Constants = 32,
|
||||
|
||||
// description
|
||||
Dynamic = 64,
|
||||
}
|
||||
|
||||
class sunOperand : sunNode {
|
||||
|
@ -71,7 +108,7 @@ namespace arookas {
|
|||
}
|
||||
}
|
||||
|
||||
class sunTernaryOperator : sunNode {
|
||||
class sunTernaryOperator : sunNode, sunTerm {
|
||||
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; } }
|
||||
|
@ -88,10 +125,14 @@ namespace arookas {
|
|||
FalseBody.Compile(context);
|
||||
context.Text.ClosePoint(trueEpilogue);
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return Condition.Analyze(context) | TrueBody.Analyze(context) | FalseBody.Analyze(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// increment/decrement
|
||||
class sunPostfixAugment : sunOperand {
|
||||
class sunPostfixAugment : sunOperand, sunTerm {
|
||||
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
||||
public sunAugment Augment { get { return this[1] as sunAugment; } }
|
||||
|
||||
|
@ -108,9 +149,13 @@ namespace arookas {
|
|||
}
|
||||
Augment.Compile(context, symbol);
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Augments;
|
||||
}
|
||||
}
|
||||
|
||||
class sunPrefixAugment : sunOperand {
|
||||
class sunPrefixAugment : sunOperand, sunTerm {
|
||||
public sunAugment Augment { get { return this[0] as sunAugment; } }
|
||||
public sunIdentifier Variable { get { return this[1] as sunIdentifier; } }
|
||||
|
||||
|
@ -127,6 +172,10 @@ namespace arookas {
|
|||
symbol.CompileGet(context);
|
||||
}
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Augments;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class sunAugment : sunNode {
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace arookas {
|
|||
}
|
||||
}
|
||||
|
||||
class sunFunctionCall : sunNode {
|
||||
class sunFunctionCall : sunNode, sunTerm {
|
||||
public sunIdentifier Function { get { return this[0] as sunIdentifier; } }
|
||||
public sunNode Arguments { get { return this[1] as sunNode; } }
|
||||
|
||||
|
@ -47,6 +47,10 @@ namespace arookas {
|
|||
context.Text.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Calls | sunExpressionFlags.Dynamic;
|
||||
}
|
||||
}
|
||||
|
||||
class sunParameterList : sunNode {
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Globalization;
|
|||
using System.Text;
|
||||
|
||||
namespace arookas {
|
||||
class sunIntLiteral : sunToken<int> { // base-10 integer
|
||||
class sunIntLiteral : sunToken<int>, sunTerm { // base-10 integer
|
||||
public sunIntLiteral(sunSourceLocation location, string literal)
|
||||
: base(location) {
|
||||
Value = Int32.Parse(literal);
|
||||
|
@ -14,6 +14,10 @@ namespace arookas {
|
|||
: base(location) { }
|
||||
|
||||
public override void Compile(sunContext context) { context.Text.PushInt(Value); }
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Literals;
|
||||
}
|
||||
}
|
||||
|
||||
class sunHexLiteral : sunIntLiteral { // base-16 integer
|
||||
|
@ -31,7 +35,7 @@ namespace arookas {
|
|||
}
|
||||
}
|
||||
|
||||
class sunFloatLiteral : sunToken<float> {
|
||||
class sunFloatLiteral : sunToken<float>, sunTerm {
|
||||
public sunFloatLiteral(sunSourceLocation location, string literal)
|
||||
: base(location) {
|
||||
Value = Single.Parse(literal);
|
||||
|
@ -40,9 +44,13 @@ namespace arookas {
|
|||
public override void Compile(sunContext context) {
|
||||
context.Text.PushFloat(Value);
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Literals;
|
||||
}
|
||||
}
|
||||
|
||||
class sunStringLiteral : sunToken<string> {
|
||||
class sunStringLiteral : sunToken<string>, sunTerm {
|
||||
public sunStringLiteral(sunSourceLocation location, string literal)
|
||||
: base(location) {
|
||||
Value = UnescapeString(literal.Substring(1, literal.Length - 2)); // remove enclosing quotes
|
||||
|
@ -123,6 +131,10 @@ namespace arookas {
|
|||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Literals;
|
||||
}
|
||||
}
|
||||
|
||||
class sunIdentifier : sunToken<string> {
|
||||
|
|
|
@ -54,42 +54,46 @@
|
|||
}
|
||||
}
|
||||
|
||||
class sunIntCast : sunNode {
|
||||
abstract class sunCast : sunNode, sunTerm {
|
||||
public sunExpression Argument { get { return this[0] as sunExpression; } }
|
||||
|
||||
protected sunCast(sunSourceLocation location)
|
||||
: base(location) { }
|
||||
|
||||
protected void Compile(sunContext context, sunBuiltinSymbol symbol) {
|
||||
Argument.Compile(context);
|
||||
context.Text.CallBuiltin(symbol.Index, 1);
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
return sunExpressionFlags.Casts | Argument.Analyze(context);
|
||||
}
|
||||
}
|
||||
|
||||
class sunIntCast : sunCast {
|
||||
public sunIntCast(sunSourceLocation location)
|
||||
: base(location) { }
|
||||
|
||||
public override void Compile(sunContext context) {
|
||||
var builtinInfo = context.ResolveSystemBuiltin("int");
|
||||
Argument.Compile(context);
|
||||
context.Text.CallBuiltin(builtinInfo.Index, 1);
|
||||
Compile(context, context.ResolveSystemBuiltin("int"));
|
||||
}
|
||||
}
|
||||
|
||||
class sunFloatCast : sunNode {
|
||||
public sunExpression Argument { get { return this[0] as sunExpression; } }
|
||||
|
||||
class sunFloatCast : sunCast {
|
||||
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);
|
||||
Compile(context, context.ResolveSystemBuiltin("float"));
|
||||
}
|
||||
}
|
||||
|
||||
class sunTypeofCast : sunNode {
|
||||
public sunExpression Argument { get { return this[0] as sunExpression; } }
|
||||
|
||||
class sunTypeofCast : sunCast {
|
||||
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);
|
||||
Compile(context, context.ResolveSystemBuiltin("typeof"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
namespace arookas {
|
||||
class sunStorableReference : sunNode {
|
||||
class sunStorableReference : sunNode, sunTerm {
|
||||
public sunIdentifier Storable { get { return this[0] as sunIdentifier; } }
|
||||
|
||||
public sunStorableReference(sunSourceLocation location)
|
||||
|
@ -8,6 +8,17 @@
|
|||
public override void Compile(sunContext context) {
|
||||
context.MustResolveStorable(Storable).Compile(context);
|
||||
}
|
||||
|
||||
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {
|
||||
var symbol = context.MustResolveStorable(Storable);
|
||||
if (symbol is sunVariableSymbol) {
|
||||
return sunExpressionFlags.Variables | sunExpressionFlags.Dynamic;
|
||||
}
|
||||
else if (symbol is sunConstantSymbol) {
|
||||
return sunExpressionFlags.Constants;
|
||||
}
|
||||
return sunExpressionFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
class sunVariableDeclaration : sunNode {
|
||||
|
|
Loading…
Add table
Reference in a new issue