4 using System.Collections.Generic;
5 using SiliconStudio.Shaders.Ast;
7 namespace SiliconStudio.Shaders.Visitor
14 private static readonly List<string> hlslScalarTypeNames =
31 private readonly Stack<double> values;
40 values =
new Stack<double>();
56 Visit((LiteralExpression) expression);
60 VisitDynamic(expression);
63 if (values.Count == 1)
64 result.Value = values.Pop();
67 result.Error(
"Cannot evaluate expression {0}", expression.Span, expression);
76 result.Warning(
"Expression evaluation [{0}] is not supported", expression.Span, expression);
83 Visit((
Node) binaryExpression);
85 var rightValue = values.Pop();
86 var leftValue = values.Pop();
88 switch (binaryExpression.Operator)
90 case BinaryOperator.Plus:
91 values.Push(leftValue + rightValue);
93 case BinaryOperator.Minus:
94 values.Push(leftValue - rightValue);
96 case BinaryOperator.Multiply:
97 values.Push(leftValue*rightValue);
99 case BinaryOperator.Divide:
100 values.Push(leftValue/rightValue);
102 case BinaryOperator.Modulo:
103 values.Push(leftValue%rightValue);
105 case BinaryOperator.LeftShift:
106 values.Push((int) leftValue << (
int) rightValue);
108 case BinaryOperator.RightShift:
109 values.Push((int) leftValue >> (
int) rightValue);
111 case BinaryOperator.BitwiseOr:
112 values.Push(((int) leftValue) | ((int) rightValue));
114 case BinaryOperator.BitwiseAnd:
115 values.Push(((int) leftValue) & ((int) rightValue));
117 case BinaryOperator.BitwiseXor:
118 values.Push(((int) leftValue) ^ ((int) rightValue));
121 result.Error(
"Binary operator [{0}] is not supported", binaryExpression.Span, binaryExpression);
151 var methodName = (methodInvocationExpression.Target as TypeReferenceExpression).Type.Name.Text;
152 if (hlslScalarTypeNames.Contains(methodName))
155 var subResult = evaluator.Evaluate(methodInvocationExpression.Arguments[0]);
157 if (subResult.Value == null)
158 result.Error(
"Unable to evaluate cast [{0}]", methodInvocationExpression.Span, methodInvocationExpression);
163 values.Push(Convert.ToDouble(subResult.Value));
167 result.Error(e.Message, methodInvocationExpression.Span);
168 result.Error(
"Unable to cast the value [{0}]", methodInvocationExpression.Span, methodInvocationExpression);
173 result.Error(
"Method invocation expression evaluation [{0}] is not supported", methodInvocationExpression.Span, methodInvocationExpression);
181 Visit((
Node)variableReferenceExpression);
183 var variableDeclaration = variableReferenceExpression.TypeInference.Declaration as
Variable;
184 if (variableDeclaration == null)
186 result.Error(
"Unable to find variable [{0}]", variableReferenceExpression.Span, variableReferenceExpression);
188 else if (variableDeclaration.InitialValue == null)
190 result.Error(
"Variable [{0}] used in expression is not constant", variableReferenceExpression.Span, variableDeclaration);
195 var subResult = evaluator.Evaluate(variableDeclaration.InitialValue);
196 subResult.CopyTo(result);
198 if (subResult.HasErrors)
204 values.Push(Convert.ToDouble(subResult.Value));
213 values.Push(Convert.ToDouble(literalExpression.Literal.Value));
221 Visit((
Node)parenthesizedExpression);
228 Visit((
Node)unaryExpression);
230 var value = values.Pop();
232 switch (unaryExpression.Operator)
234 case UnaryOperator.Plus:
237 case UnaryOperator.Minus:
240 case UnaryOperator.PreIncrement:
241 case UnaryOperator.PostIncrement:
246 case UnaryOperator.PreDecrement:
247 case UnaryOperator.PostDecrement:
252 result.Error(
"Unary operator [{0}] is not supported", unaryExpression.Span, unaryExpression);
ExpressionResult Evaluate(Expression expression)
Evaluates the specified expression.
Describes a binary expression.
virtual void Visit(BinaryExpression binaryExpression)
virtual void Visit(LiteralExpression literalExpression)
An expression surrounded by parenthesis.
virtual void Visit(MethodInvocationExpression methodInvocationExpression)
A reference to a variable.
Expression Target
Gets or sets the target.
virtual void Visit(ParenthesizedExpression parenthesizedExpression)
virtual void Visit(Expression expression)
ExpressionEvaluator()
Initializes a new instance of the ExpressionEvaluator class.
virtual void Visit(UnaryExpression unaryExpression)
A reference to a variable.
virtual void Visit(VariableReferenceExpression variableReferenceExpression)