private Variable GetUniform(Expression expression) { VariableReferenceExpression variableRef = null; while (expression != null) { if (expression is MemberReferenceExpression) { expression = ((MemberReferenceExpression)expression).Target; } else if (expression is IndexerExpression) { expression = ((IndexerExpression)expression).Target; } else { variableRef = expression as VariableReferenceExpression; break; } } if (variableRef != null) { var variable = variableRef.TypeInference.Declaration as Variable; // If the variable is a global uniform, non static/const and is not already in the list used then return (variable != null && shader.Declarations.Contains(variable) && !variable.Qualifiers.Contains(Ast.Hlsl.StorageQualifier.Static) && !variable.Qualifiers.Contains(Ast.StorageQualifier.Const)) ? variable : null; } return null; }
public bool IsVariableAsGlobalTemporary(Expression expression) { var variable = GetUniform(expression); if (variable == null) return false; return IsVariableAsGlobalTemporary(variable); }
public bool IsUniformReadWrite(Expression expression) { var variable = GetUniform(expression); if (variable == null) return false; return IsUniformReadWrite(variable); }
protected void Visit(Expression expression) { expression.TypeInference.Declaration = null; expression.TypeInference.TargetType = null; expression.TypeInference.ExpectedType = null; Visit((Node)expression); }
private static ExpressionList Clone(ExpressionList expression) { var parameters = new Expression[expression.Count]; for (int i = 0; i < expression.Count; ++i) parameters[i] = Clone(expression[i]); return new ExpressionList(parameters); }
private Variable FindGlobalVariable(Expression expression) { var variableRef = expression as VariableReferenceExpression; if (variableRef != null) { var variable = variableRef.TypeInference.Declaration as Variable; if (variable != null) { // If a variable has an initial value, find the global variable if (!shader.Declarations.Contains(variable) && variable.InitialValue != null) { return this.FindGlobalVariable(variable.InitialValue); } variable = (Variable)variable.GetTag(ScopeValueKey) ?? variable; // Is this a global variable? if (shader.Declarations.Contains(variable)) { return variable; } } } return null; }
private static Expression Clone(Expression expression) { if (expression is ArrayInitializerExpression) return Clone((ArrayInitializerExpression)expression); if (expression is BinaryExpression) return Clone((BinaryExpression)expression); if (expression is ConditionalExpression) return Clone((ConditionalExpression)expression); if (expression is EmptyExpression) return Clone((EmptyExpression)expression); if (expression is ExpressionList) return Clone((ExpressionList)expression); if (expression is IndexerExpression) return Clone((IndexerExpression)expression); if (expression is KeywordExpression) return Clone((KeywordExpression)expression); if (expression is LiteralExpression) return Clone((LiteralExpression)expression); if (expression is MemberReferenceExpression) return Clone((MemberReferenceExpression)expression); if (expression is MethodInvocationExpression) return Clone((MethodInvocationExpression)expression); if (expression is ParenthesizedExpression) return Clone((ParenthesizedExpression)expression); if (expression is TypeReferenceExpression) return Clone((TypeReferenceExpression)expression); if (expression is UnaryExpression) return Clone((UnaryExpression)expression); if (expression is VariableReferenceExpression) return Clone((VariableReferenceExpression)expression); return null; }
private void Initialize(Expression target, params Expression[] arguments) { Target = target; Arguments = new List<Expression>(); if (arguments != null) Arguments.AddRange(arguments); }
/// <summary> /// Initializes a new instance of the <see cref="Variable"/> class. /// </summary> /// <param name="type">The type.</param> /// <param name="name">The name.</param> /// <param name="initialValue">The initial value.</param> public Variable(TypeBase type, string name, Expression initialValue = null) { Type = type; Name = new Identifier(name); InitialValue = initialValue; Attributes = new List<AttributeBase>(); Qualifiers = Qualifier.None; }
private Expression ProcessExpression(Expression expression) { if (expression.TypeInference.TargetType != null && expression.TypeInference.TargetType.IsStreamsType()) { var mre = new MemberReferenceExpression(expression, typeInference.Name) { TypeInference = { Declaration = typeInference, TargetType = typeInference.Type.ResolveType() } }; if (arrayIndex == null) return mre; else { var ire = new IndexerExpression(mre, arrayIndex); return ire; } } return expression; }
private Expression Visit(Expression expression) { Visit((Node)expression); if ((expression is VariableReferenceExpression || expression is MemberReferenceExpression || expression is IndexerExpression) && expression.TypeInference.TargetType is StreamsType) // TODO: exclude constants, test real type { var mre = new MemberReferenceExpression(expression, typeInference.Name) { TypeInference = { Declaration = typeInference, TargetType = typeInference.Type.ResolveType() } }; if (arrayIndex == null) return mre; else { var ire = new IndexerExpression(mre, arrayIndex); return ire; } } return expression; }
/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">The expression.</param> /// <returns>Result of the expression evaluated</returns> public ExpressionResult Evaluate(Expression expression) { values.Clear(); result = new ExpressionResult(); // Small optim, if LiteralExpression, we perform a direct eval. var literalExpression = expression as LiteralExpression; if (literalExpression != null) { Visit(literalExpression); } else { VisitDynamic(expression); } if (values.Count == 1) result.Value = values.Pop(); else { result.Error("Cannot evaluate expression {0}", expression.Span, expression); } return result; }
public ExpressionNodeCouple(Expression expression, Node node) { Expression = expression; Node = node; }
public bool Equals(Expression other) { return !ReferenceEquals(null, other); }
/// <summary> /// Adds a stream usage to the current method /// </summary> /// <param name="variable">the stream Variable</param> /// <param name="expression">the calling expression</param> /// <param name="usage">the encountered usage</param> private void AddStreamUsage(Variable variable, SiliconStudio.Shaders.Ast.Expression expression, StreamUsage usage) { currentStreamUsageList.Add(new StreamUsageInfo { CallType = StreamCallType.Member, Variable = variable, Expression = expression, Usage = usage }); }
public static Expression Run(Expression expression) { return Clone(expression); }
private static MethodInvocationExpression Clone(MethodInvocationExpression expression) { var parameters = new Expression[expression.Arguments.Count]; for (int i = 0; i < expression.Arguments.Count; ++i) parameters[i] = Clone(expression.Arguments[i]); return new MethodInvocationExpression(Clone(expression.Target), parameters); }
/// <summary> /// Initializes a new instance of the <see cref="Parameter"/> class. /// </summary> /// <param name="type">The type.</param> /// <param name="name">The name.</param> /// <param name="initialValue">The initial value.</param> public Parameter(TypeBase type, string name = null, Expression initialValue = null) : base(type, name, initialValue) { }
/// <summary> /// Initializes a new instance of the <see cref="MixinStatement" /> class. /// </summary> /// <param name="type">The type.</param> /// <param name="mixin">The mixin.</param> public MixinStatement(MixinStatementType type, Expression mixin) { Type = type; Value = mixin; }
/// <summary> /// Look for extern qualifier in expression typeinference /// </summary> /// <param name="expression">the expression</param> /// <returns>true if there is a reference to an extern variable</returns> private static bool HasExternQualifier(Expression expression) { var varDecl = expression.TypeInference.Declaration as Variable; if (varDecl != null && varDecl.Qualifiers.Contains(StorageQualifier.Extern)) return !(varDecl.InitialValue is VariableReferenceExpression) || (varDecl.InitialValue as VariableReferenceExpression).Name.Text != "stage"; if (expression is MemberReferenceExpression) return HasExternQualifier((expression as MemberReferenceExpression).Target); return false; }
/// <summary> /// Writes the initializer. /// </summary> /// <param name="expression"> /// The expression. /// </param> public virtual void WriteInitializer(Expression expression) { if (expression == null) return; WriteSpace().Write("="); WriteSpace(); VisitDynamic(expression); }
/// <summary> /// Initializes a new instance of the <see cref="IndexerExpression"/> class. /// </summary> /// <param name="target"> /// The target. /// </param> /// <param name="index"> /// The index. /// </param> public IndexerExpression(Expression target, Expression index) { this.Target = target; this.Index = index; }
/// <summary> /// Initializes a new instance of the <see cref="ConditionalExpression"/> class. /// </summary> /// <param name="condition">The condition.</param> /// <param name="left">The left.</param> /// <param name="right">The right.</param> public ConditionalExpression(Expression condition, Expression left, Expression right) { Condition = new ParenthesizedExpression(condition); Left = left; Right = right; }
/// <summary> /// Initializes a new instance of the <see cref="ExpressionStatement"/> class. /// </summary> /// <param name="expression"> /// The expression. /// </param> public ExpressionStatement(Expression expression) { Expression = expression; }
/// <summary> /// Initializes a new instance of the <see cref="ReturnStatement"/> class. /// </summary> /// <param name="value">The value.</param> public ReturnStatement(Expression value) { Value = value; }
/// <summary> /// Gets a name of the variable referenced by an expression. /// </summary> /// <param name="expression">The expression.</param> /// <returns>Name of the variable referenced. If the expression is not a VariableReferenceExpression, returns null</returns> public static string GetVariableName(Expression expression) { var variableReferenceExpression = expression as VariableReferenceExpression; return variableReferenceExpression == null ? null : variableReferenceExpression.Name.Text; }
/// <summary> /// Find the correct variable inference /// </summary> /// <param name="expression"></param> /// <param name="mixin"></param> /// <returns></returns> private Variable FindVariable(Expression expression, ref ModuleMixin mixin) { Variable result = null; var index = 0; if (expression is VariableReferenceExpression) { result = FindVariableInMixin((expression as VariableReferenceExpression).Name.Text, mixin); } else if (expression is MemberReferenceExpression) { var memberExpression = expression as MemberReferenceExpression; var target = memberExpression.Target; if (target.TypeInference.Declaration is Variable) FindVariable(target, ref mixin); else if (target.TypeInference.Declaration is ShaderClassType || target.TypeInference.TargetType is ShaderClassType) FindShader(target, ref mixin); result = FindVariableInMixin(memberExpression.Member.Text, mixin); } else if (expression is IndexerExpression) { var indexerExpression = expression as IndexerExpression; var target = indexerExpression.Target; if (target.TypeInference.Declaration is Variable) result = FindVariable(target, ref mixin); index = (int)(indexerExpression.Index as LiteralExpression).Value; } if (result is Variable && (result as Variable).Qualifiers.Contains(XenkoStorageQualifier.Extern) && !((result as Variable).Type is ArrayType)) mixin = CompositionsPerVariable[result as Variable][index]; return result; }
/// <summary> /// Test if the expression is from a stage nitialized one /// </summary> /// <param name="expression">the expression</param> /// <returns>true if it is the case, false otherwise</returns> private bool IsStageInitMember(Expression expression) { if (expression != null) return parsingInfo.StageInitializedVariables.Contains(expression.TypeInference.Declaration) || (expression is MemberReferenceExpression && IsStageInitMember((expression as MemberReferenceExpression).Target)); return false; }
private MethodDeclaration FindMethod(Expression expression, ref ModuleMixin mixin) { if (expression is MemberReferenceExpression) { var memberExpression = expression as MemberReferenceExpression; var target = memberExpression.Target; if (target.TypeInference.Declaration is Variable) FindVariable(target, ref mixin); else if (target.TypeInference.Declaration is ShaderClassType || target.TypeInference.TargetType is ShaderClassType) FindShader(target, ref mixin); } var topMixin = GetTopMixin(mixin); if (topMixin == null) { log.Error(XenkoMessageCode.ErrorTopMixinNotFound, expression.Span, expression); return null; } var foundMethod = topMixin.GetMethodFromExpression(expression); if (foundMethod == null) { log.Error(XenkoMessageCode.ErrorCallNotFound, expression.Span, expression); return null; } if (foundMethod.Qualifiers.Contains(XenkoStorageQualifier.Abstract)) { log.Error(XenkoMessageCode.ErrorCallToAbstractMethod, expression.Span, expression, foundMethod); return null; } return foundMethod; }
/// <summary> /// Adds the expression to the reference list of the variable /// </summary> /// <param name="expression">the Expression</param> private void AddToVariablesReference(Expression expression) { var variable = expression.TypeInference.Declaration as Variable; if (variable != null && variable.ContainsTag(XenkoTags.ShaderScope)) { if (expression.ContainsTag(XenkoTags.StaticRef) || variable.Qualifiers.Contains(StorageQualifier.Static)) parsingInfo.StaticReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); else if (expression.ContainsTag(XenkoTags.ExternRef)) parsingInfo.ExternReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); else if (expression.ContainsTag(XenkoTags.StageInitRef)) parsingInfo.StageInitReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); else parsingInfo.ClassReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); } else { parsingInfo.NavigableNodes.Add(expression); } }
private void FindShader(Expression expression, ref ModuleMixin mixin) { if (expression is MemberReferenceExpression) { var memberExpression = expression as MemberReferenceExpression; var target = memberExpression.Target; if (target.TypeInference.Declaration is Variable) FindVariable(target, ref mixin); var mixinName = (expression.TypeInference.Declaration as ShaderClassType).Name.Text; mixin = mixin.MixinName == mixinName ? mixin : mixin.InheritanceList.FirstOrDefault(x => x.MixinName == mixinName); } else if (expression is IndexerExpression) { var indexerExpression = expression as IndexerExpression; var target = indexerExpression.Target; Variable result = null; if (target.TypeInference.Declaration is Variable) result = FindVariable(target, ref mixin); var index = (int)(indexerExpression.Index as LiteralExpression).Value; if (result is Variable && (result as Variable).Qualifiers.Contains(XenkoStorageQualifier.Extern)) mixin = CompositionsPerVariable[result as Variable][index]; } }