StageValue ProcessMetaProperty(MetaLocation loc, bool required = true) { StageValue result; if (ProcessedMetaProperties.TryGetValue(loc, out result)) { return(new StageValue(result.Value.CopyExpression(new CopyState(DrawState.Path.DrawBlock.Method)), result.MinStage, result.MaxStage)); } var mp = GetProperty(loc); var def = GetValidDefinition(loc); if (def == null) { if (required) { Log.Error(CreateTrace(mp, loc, null), ErrorCode.E5004, "No valid definition of " + mp.Name.Quote() + " was found in " + Path.Quote()); return(new StageValue(Expression.Invalid, MetaStage.Const)); } return(new StageValue(null, MetaStage.Const)); } // Detect circular references (should not happen) foreach (var ploc in LocationStack) { if (ploc == loc) { Log.Error(CreateTrace(mp, loc, LocationStack), ErrorCode.E5005, "Circular reference to " + mp.Name.Quote() + " detected while processing " + Path.Quote()); return(new StageValue(Expression.Invalid, MetaStage.Const)); } } LocationStack.Add(loc); switch (def.Value.StatementType) { case StatementType.Expression: result = ProcessValue(def.Value as Expression); result.Value = new FunctionCompiler(Compiler, mp).CompileImplicitCast(def.Value.Source, mp.ReturnType, result.Value); break; case StatementType.Scope: result = ScopeProcessor.Process(this, def.Value as Scope); break; case StatementType.FixedArrayDeclaration: result = ProcessFixedArrayDeclaration(def.Value as FixedArrayDeclaration); break; default: // Should not happen Log.Error(def.Value.Source, ErrorCode.I5006, "<" + def.Value.StatementType + "> is not supported by ShaderGenerator"); result = new StageValue(Expression.Invalid, MetaStage.Const); ProcessedMetaProperties.Add(loc, result); return(result); } LocationStack.RemoveLast(); if (!InlineOnStage(result.MinStage, result.Value)) { MetaStage resultStage; Scope resultScope; switch (result.MinStage) { case MetaStage.Pixel: resultStage = MetaStage.Pixel; resultScope = PixelScope; break; case MetaStage.Vertex: resultStage = MetaStage.Vertex; resultScope = VertexScope; break; case MetaStage.Volatile: resultStage = MetaStage.Volatile; resultScope = FrameScope; break; default: resultStage = MetaStage.ReadOnly; resultScope = InitScope; break; } var val = new PlaceholderValue(mp, loc, result.Value, resultStage); result = new StageValue(new PlaceholderReference(val), val.Stage); resultScope.Statements.Add(new VariableDeclaration(mp.Source, null, CreateLocalName(mp, loc), val.ReturnType, VariableType.Default, val)); } else if (!(result.Value is PlaceholderReference) && !(result.Value is PlaceholderValue) && !(result.Value is Constant)) { result.Value = new PlaceholderValue(mp, loc, result.Value, MetaStage.Undefined); } ProcessedMetaProperties.Add(loc, result); return(result); }