Example #1
0
        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);
        }