Added expression analysis.

Also gave the AST cast nodes a base class while I was at it.
This commit is contained in:
arookas 2015-12-28 14:22:54 -05:00
parent 6be1779781
commit 54bd3618e3
5 changed files with 108 additions and 28 deletions

View file

@ -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 {

View file

@ -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 {

View file

@ -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> {

View file

@ -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"));
}
}

View file

@ -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 {