79 lines
2.8 KiB
C#
79 lines
2.8 KiB
C#
using System;
|
|
using Upsilon.Parser;
|
|
|
|
namespace Upsilon.Evaluator
|
|
{
|
|
public static class Evaluator
|
|
{
|
|
public static object Evaluate(this ScriptSyntax e)
|
|
{
|
|
return EvaluateExpression(e.Statement);
|
|
}
|
|
|
|
public static object Evaluate(this ExpressionSyntax e)
|
|
{
|
|
return EvaluateExpression(e);
|
|
}
|
|
|
|
private static object EvaluateExpression(ExpressionSyntax e)
|
|
{
|
|
switch (e.Kind)
|
|
{
|
|
case SyntaxKind.UnaryExpression:
|
|
return EvaluateUnaryExpression((UnaryExpressionSyntax) e);
|
|
case SyntaxKind.BinaryExpression:
|
|
return EvaluateBinaryExpression((BinaryExpressionSyntax) e);
|
|
case SyntaxKind.LiteralExpression:
|
|
return ((LiteralExpressionSyntax) e).Value;
|
|
case SyntaxKind.ParenthesizedExpression:
|
|
return ((ParenthesizedExpressionSyntax) e).Expression.Evaluate();
|
|
default:
|
|
throw new Exception("Invalid expression: " + e.Kind);
|
|
}
|
|
}
|
|
|
|
private static object EvaluateUnaryExpression(UnaryExpressionSyntax e)
|
|
{
|
|
var operand = EvaluateExpression(e.Expression);
|
|
switch (e.Operator.Kind)
|
|
{
|
|
case SyntaxKind.Plus:
|
|
return operand;
|
|
case SyntaxKind.Minus:
|
|
return -(double) operand;
|
|
case SyntaxKind.NotKeyword:
|
|
return !(bool)operand;
|
|
default:
|
|
throw new Exception("Invalid Unary Operator: " + e.Operator.Kind);
|
|
}
|
|
}
|
|
|
|
private static object EvaluateBinaryExpression(BinaryExpressionSyntax e)
|
|
{
|
|
var left = EvaluateExpression(e.Left);
|
|
var right = EvaluateExpression(e.Right);
|
|
switch (e.Operator.Kind)
|
|
{
|
|
case SyntaxKind.Plus:
|
|
return (double)left + (double)right;
|
|
case SyntaxKind.Minus:
|
|
return (double)left - (double)right;
|
|
case SyntaxKind.Star:
|
|
return (double)left * (double)right;
|
|
case SyntaxKind.Slash:
|
|
return (double)left / (double)right;
|
|
case SyntaxKind.AndKeyword:
|
|
return (bool)left && (bool)right;
|
|
case SyntaxKind.OrKeyword:
|
|
return (bool)left || (bool)right;
|
|
case SyntaxKind.EqualsEquals:
|
|
return Equals(left, right);
|
|
case SyntaxKind.TildeEquals:
|
|
return !Equals(left, right);
|
|
default:
|
|
throw new Exception("Invalid Binary Operator: " + e.Operator.Kind);
|
|
}
|
|
}
|
|
|
|
}
|
|
} |