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()); }
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(")"); }
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); }