Ejemplo n.º 1
0
        Statement CompileFixedArrayDeclaration(AstFixedArrayDeclaration e)
        {
            var s    = e.Type;
            var size = s.OptionalSize != null
                ? CompileImplicitCast(s.OptionalSize.Source, Essentials.Int,
                                      CompileExpression(s.OptionalSize))
                : null;

            var elementType = NameResolver.GetType(Namescope, s.ElementType);
            var dt          = new FixedArrayType(s.Source, elementType, size, Essentials.Int);

            VerifyVariableName(e.Source, e.Name.Symbol);

            var fixedInit = e.OptionalValue as AstFixedArrayInitializer;

            if (fixedInit != null)
            {
                return(CompileFixedArrayDeclaration(e.Source, dt, e.Name.Symbol, fixedInit));
            }

            var var = new Variable(e.Source, Function, e.Name.Symbol, dt, 0,
                                   e.OptionalValue != null
                ? CompileImplicitCast(e.Source, dt, CompileExpression(e.OptionalValue))
                : null);

            CurrentVariableScope.Variables[e.Name.Symbol] = var;
            return(new FixedArrayDeclaration(var, null));
        }
Ejemplo n.º 2
0
        DataType ParameterizeType(Dictionary <DataType, DataType> map, DataType arg)
        {
            if (arg == null)
            {
                return(null);
            }

            DataType result;

            if (map.TryGetValue(arg, out result))
            {
                return(result);
            }

            if (arg is RefArrayType)
            {
                result = GetArray(ParameterizeType(map, arg.ElementType));
            }
            else if (arg is FixedArrayType)
            {
                result = new FixedArrayType(
                    arg.Source,
                    ParameterizeType(map, arg.ElementType),
                    ((FixedArrayType)arg).OptionalSize,
                    _ilf.Essentials.Int);
            }
            else if (arg.IsNestedType && arg.ParentType.IsFlattenedParameterization)
            {
                var p = ParameterizeType(map, arg.ParentType);

                if (arg.IsGenericParameter && p.IsGenericDefinition)
                {
                    // Should not be necessary
                    foreach (var pp in p.GenericParameters)
                    {
                        if (pp.UnoName == arg.UnoName)
                        {
                            result = pp;
                            break;
                        }
                    }
                }
                else
                {
                    bool innerTypeFound = false;

                    foreach (var it in p.NestedTypes)
                    {
                        if (arg.MasterDefinition == it.MasterDefinition)
                        {
                            if (it.IsGenericDefinition)
                            {
                                var pargs = new DataType[arg.GenericArguments.Length];

                                for (int i = 0, l = pargs.Length; i < l; i++)
                                {
                                    pargs[i] = ParameterizeType(map, arg.GenericArguments[i]);
                                }

                                result = Parameterize(it.Source, it, pargs);
                            }
                            else
                            {
                                result = it;
                            }

                            innerTypeFound = true;
                            break;
                        }
                    }

                    if (!innerTypeFound)
                    {
                        // Should not be necessary
                        foreach (var m in p.Methods)
                        {
                            if (m.IsGenericDefinition &&
                                m.GenericType.MasterDefinition == arg.MasterDefinition)
                            {
                                result = m.GenericType;
                                break;
                            }
                        }
                    }
                }
            }
            else if (arg.IsGenericParameterization)
            {
                var pargs = new DataType[arg.GenericArguments.Length];

                for (int i = 0, l = pargs.Length; i < l; i++)
                {
                    pargs[i] = ParameterizeType(map, arg.GenericArguments[i]);
                }

                result = Parameterize(arg.Source, arg.GenericDefinition, pargs);
            }
            else
            {
                result = arg;
            }

            if (result != null)
            {
                map.Add(arg, result);
                return(result);
            }

            throw new FatalException(arg.Source, ErrorCode.I0000, "Failed to parameterize " + arg.Quote());
        }
Ejemplo n.º 3
0
        internal StageValue ProcessStageChange(StageValue s, MetaStage fromStage, MetaStage toStage, MetaLocation loc, MetaProperty mp)
        {
            if (s.Value == null)
            {
                return(new StageValue(null, toStage));
            }

            if (s.MinStage > fromStage)
            {
                Log.Error(s.Value.Source, ErrorCode.I5016, "Stage error");
                return(new StageValue(Expression.Invalid, toStage));
            }

            switch (toStage)
            {
            case MetaStage.Pixel:
            case MetaStage.Vertex:
                if (fromStage == MetaStage.Vertex && toStage == MetaStage.Pixel)
                {
                    // Vertex -> Pixel: Varying

                    var key = s.Value.ToString();

                    int index;
                    if (!Varyings.TryGetValue(key, out index))
                    {
                        index = DrawState.Varyings.Count;
                        DrawState.Varyings.Add(new ShaderVariable(s.Value.ReturnType, CreateShaderName(mp, loc, s.Value), s.Value));
                        Varyings.Add(key, index);
                    }

                    return(new StageValue(new LoadVarying(s.Value.Source, DrawState, index), MetaStage.Pixel, MetaStage.Pixel));
                }
                else if (s.Value.ReturnType == Essentials.Bool || s.Value.ReturnType == Essentials.Int)
                {
                    return(ProcessShaderConstant(s, loc, mp));
                }
                else
                {
                    // Init,Frame -> Vertex,Pixel: Uniform

                    s = ProcessStage(s, MetaStage.Volatile, MetaStage.Volatile);

                    var val = s.Value.ActualValue;
                    var dt  = val.ReturnType;
                    var key = val.ToString();

                    int index;
                    if (!Uniforms.TryGetValue(key, out index))
                    {
                        index = DrawState.Uniforms.Count;

                        switch (dt.TypeType)
                        {
                        case TypeType.FixedArray:
                            // Ugly workaround. ResolvedMetaPropertyValue could already be an address
                            if (!(val is PlaceholderValue && (val as PlaceholderValue).Value is AddressOf))
                            {
                                val = new AddressOf(val.ActualValue, AddressType.Const);
                            }

                            break;

                        case TypeType.RefArray:
                            var at = dt as RefArrayType;
                            var et = at.ElementType;

                            var size = ProcessShaderConstant(
                                new StageValue(ILFactory.GetProperty(s.Value.Source, s.Value, "Length"), s.MinStage, s.MaxStage),
                                loc, mp).Value;

                            dt = new FixedArrayType(s.Value.Source, et, size, Essentials.Int);
                            break;
                        }

                        DrawState.Uniforms.Add(new ShaderVariable(dt, CreateShaderName(mp, loc, val), val));
                        Uniforms.Add(key, index);
                    }

                    Expression u = new LoadUniform(s.Value.Source, DrawState, index);

                    if (u.ReturnType.IsFixedArray)
                    {
                        u = new AddressOf(u, AddressType.Const);
                    }

                    return(new StageValue(u, MetaStage.Vertex, MetaStage.Pixel));
                }

            case MetaStage.Volatile:
                if (fromStage <= MetaStage.ReadOnly)
                {
                    // Init -> Frame: Field

                    var src = s.Value.Source;
                    var dt  = Path.DrawBlock.Method.DeclaringType;
                    var obj = new This(src, dt).Address;
                    var key = s.Value.ToString();

                    Field field;
                    if (!Fields.TryGetValue(key, out field))
                    {
                        for (int i = 0; i < InitScope.Statements.Count; i++)
                        {
                            if (InitScope.Statements[i] is StoreField)
                            {
                                var sf = InitScope.Statements[i] as StoreField;
                                if (sf.Field.ReturnType.Equals(s.Value.ReturnType) && sf.Value.ToString() == key)
                                {
                                    field = sf.Field;
                                }
                            }
                        }

                        if (field == null)
                        {
                            field = new Field(src, dt, CreateFieldName(mp, loc, s.Value),
                                              null, Modifiers.Private | Modifiers.Generated, 0, s.Value.ReturnType);
                            dt.Fields.Add(field);
                            InitScope.Statements.Add(new StoreField(src, obj, field, s.Value));
                        }

                        Fields.Add(key, field);
                    }

                    return(new StageValue(new LoadField(src, obj, field), MetaStage.ReadOnly, MetaStage.Volatile));
                }
                break;

            case MetaStage.ReadOnly:
                return(s);
            }

            Log.Error(s.Value.Source, ErrorCode.E5017, fromStage.ToLiteral().Quote() + " cannot be accessed from " + toStage.ToLiteral() + " stage while processing " + mp.Name.Quote() + " at " + mp.Source + " in " + Path.Quote() + " at " + Path.Source);
            return(new StageValue(Expression.Invalid, MetaStage.Const));
        }
Ejemplo n.º 4
0
        DataType GetTypeInternal(DataType dt)
        {
            DataType result;

            if (SwapTypes.TryGetValue(dt, out result))
            {
                return(result);
            }

            switch (dt.TypeType)
            {
            case TypeType.GenericParameter:
            {
                SwapTypes.Add(dt, dt);
                return(dt);
            }

            case TypeType.RefArray:
            {
                var at = TypeBuilder.GetArray(GetType(dt.ElementType));
                SwapTypes.Add(dt, at);
                return(at);
            }

            case TypeType.FixedArray:
            {
                var at = (FixedArrayType)dt;
                at = new FixedArrayType(at.Source, GetType(at.ElementType), at.OptionalSize, Essentials.Int);
                SwapTypes.Add(dt, at);
                return(at);
            }
            }

            result = dt;

            if (dt.IsNestedType)
            {
                if (!dt.IsGenericParameterization && dt.IsFlattenedParameterization)
                {
                    var def = GetType(dt.MasterDefinition);

                    // Transformed type was unnested
                    if (!def.IsNestedType)
                    {
                        if (def.IsGenericDefinition)
                        {
                            var args = new DataType[dt.FlattenedArguments.Length];

                            for (int i = 0; i < dt.FlattenedArguments.Length; i++)
                            {
                                args[i] = GetType(dt.FlattenedArguments[i]);
                            }

                            result = TypeBuilder.Parameterize(result.Source, def, args);
                            TypeBuilder.BuildTypes();
                            SwapTypes.Add(dt, result);
                            return(result);
                        }

                        // Unnested enum
                        SwapTypes.Add(dt, def);
                        return(def);
                    }
                }

                var pt = GetType(dt.ParentType);
                if (pt != dt.Parent)
                {
                    foreach (var it in pt.NestedTypes)
                    {
                        if (it.MasterDefinition == dt.MasterDefinition)
                        {
                            result = pt;
                            break;
                        }
                    }
                }
            }

            if (dt.IsGenericParameterization)
            {
                var args = new DataType[dt.GenericArguments.Length];

                for (int i = 0; i < dt.GenericArguments.Length; i++)
                {
                    args[i] = GetType(dt.GenericArguments[i]);
                }

                var def = result.IsGenericDefinition ? result : GetType(dt.GenericDefinition);
                result = TypeBuilder.Parameterize(dt.Source, def, args);
                TypeBuilder.BuildTypes();
            }

            SwapTypes.Add(dt, result);
            return(result);
        }