Beispiel #1
0
 public virtual void WriteAsOp(AsOp s, ExpressionUsage u)
 {
     Begin(u.IsObject());
     WriteExpression(s.Operand, ExpressionUsage.Operand);
     Write(" as ");
     WriteType(s.Source, s.ReturnType);
     End(u.IsObject());
 }
Beispiel #2
0
        public override void WriteAsOp(AsOp s, ExpressionUsage u)
        {
            Write("$AsOp(");
            WriteExpression(s.Operand);
            Write(", " + Backend.GetTypeId(s.Source, Function, s.ReturnType));

            if (IsBoxedType(s.Operand.ReturnType))
            {
                Write(", " + Backend.GetTypeId(s.Source, Function, s.Operand.ReturnType));
            }

            Write(")");
        }
Beispiel #3
0
        static bool TrySplitVirtualAppliesInDrawBlockRecursive(Compiler compiler, DrawBlock drawBlock, ref int drawBlockIndex, HashSet <Scope> drawScopes)
        {
            for (int i = 0, l = drawBlock.Members.Count; i < l; i++)
            {
                var apply = drawBlock.Members[i] as Apply;

                if (apply != null &&
                    apply.Modifier == ApplyModifier.Virtual &&
                    apply.Object != null)
                {
                    var dt        = apply.Object.ReturnType;
                    int baseIndex = drawBlockIndex;

                    Statement root   = null;
                    IfElse    lastIf = null;

                    HashSet <DataType> subSet;
                    if (compiler.BlockBuilder.FlattenedTypes.TryGetValue(dt, out subSet))
                    {
                        var subArray = subSet.ToArray();

                        // Make sure array is sorted correctly.
                        // Reverse order since this is most similar to the original order making sorting ~O(n)

                        Array.Sort(subArray,
                                   (a, b) =>
                        {
                            int al = 0, bl = 0;

                            for (var bt = a.Base; bt != null && bt != dt; bt = bt.Base)
                            {
                                al++;
                            }
                            for (var bt = b.Base; bt != null && bt != dt; bt = bt.Base)
                            {
                                bl++;
                            }

                            return(al - bl);
                        });

                        foreach (var st in subArray.Reverse())
                        {
                            if (st.IsAbstract || st.Block == null || !st.IsAccessibleFrom(apply.Source))
                            {
                                continue;
                            }

                            var obj      = new AsOp(apply.Object.Source, apply.Object, st);
                            var subBlock = CreateFlattenedVirtualApplyInDrawBlock(apply.Source, drawBlock, i, obj, st.Block);
                            var cond     = new IsOp(apply.Object.Source, apply.Object, st, compiler.Essentials.Bool);
                            var subIf    = new IfElse(subBlock.Source, cond, subBlock.DrawScope);

                            if (lastIf == null)
                            {
                                root   = subIf;
                                lastIf = subIf;
                            }
                            else
                            {
                                lastIf.OptionalElseBody = subIf;
                                lastIf = subIf;
                            }

                            drawBlock.Method.DrawBlocks.Insert(++baseIndex, subBlock);
                            TrySplitVirtualAppliesInDrawBlockRecursive(compiler, subBlock, ref baseIndex, drawScopes);
                        }
                    }

                    if (!dt.IsAbstract)
                    {
                        var baseBlock = CreateFlattenedVirtualApplyInDrawBlock(apply.Source, drawBlock, i, apply.Object, apply.Block);

                        if (lastIf == null)
                        {
                            root = baseBlock.DrawScope;
                        }
                        else
                        {
                            lastIf.OptionalElseBody = baseBlock.DrawScope;
                        }

                        drawBlock.Method.DrawBlocks.Insert(++baseIndex, baseBlock);
                        TrySplitVirtualAppliesInDrawBlockRecursive(compiler, baseBlock, ref baseIndex, drawScopes);
                    }

                    if (root != null)
                    {
                        drawBlock.DrawScope.Statements.Add(root);
                    }

                    drawScopes.Add(drawBlock.Method.DrawBlocks[drawBlockIndex].DrawScope);
                    drawBlock.Method.DrawBlocks.RemoveAt(drawBlockIndex);
                    drawBlockIndex += baseIndex - drawBlockIndex - 1;
                    return(true);
                }
            }

            return(false);
        }