[DebuggerNonUserCode] public BlockExpander(Block source, ExpansionContext ctx) { Source = source; Ctx = ctx; Stmts = new Block(); ctx.Scope = Stmts; var cloned_locals = source.Locals.Select(l => l.DeepClone()); cloned_locals.ForEach(local => ctx.Scope.Locals.Add(local)); var is_root = Ctx.Parent == null || (Ctx.Parent.Stack.Count() != Ctx.Stack.Count()); if (is_root) RetLabel = new Label(); else RetLabel.AssertNotNull(); source.ForEach(Expand); if (is_root && Stmts.LastOrDefault() is Goto) Stmts.RemoveLast(); var gotos = Stmts.Family().OfType<Goto>().Where(@goto => @goto.LabelId == RetLabel.Id).ToReadOnly(); if (is_root && gotos.IsNotEmpty()) Stmts.Add(RetLabel); }
protected internal override void TraverseBlock(Block block) { var prefixes = block.ToDictionary(s => s, s => new List<Action<IndentedWriter>>()); var evalOrder = block.CSharpEvaluationOrder(); var allRefs = evalOrder.OfType<Ref>().Where( @ref => @ref.Sym != null && @ref.Sym.IsLocal()).ToReadOnly(); var r_scopes = allRefs.ToDictionary(@ref => @ref, @ref => @ref.Scope()); block.Locals.ForEach(loc => { var refs = allRefs.Where(@ref => @ref.Sym == loc).ToReadOnly(); if (refs.IsEmpty()) return; var firstUsage = refs.First(); var firstAss = firstUsage.Parent.AssertCast<Assign>().AssertNotNull(); (firstAss.Lhs is Ref && ((Ref)firstAss.Lhs).Sym == loc).AssertTrue(); if (ReferenceEquals(r_scopes[firstUsage], block)) { prefixes[firstAss].Add(w => w.Write("var ")); } else { var stmt = firstUsage.Hierarchy().SkipWhile(n => n.Parent != block).First(); prefixes[stmt].Add(w => w.WriteLine(String.Format("{0} {1};", loc.Type == null ? "?" : loc.Type.GetCSharpRef(ToCSharpOptions.Informative), loc.Name))); } }); _writer.WriteLine("{"); _writer.Indent++; block.ForEach(c => { prefixes[c].ForEach(action => action(_writer)); Traverse(c); if (IsOneliner(c)) { if (c is Label) _writer.WriteLine(":"); else _writer.WriteLine(";"); } }); _writer.Indent--; _writer.WriteLine("}"); }
protected internal override void TraverseBlock(Block block) { block.ForEach(Traverse); Types.Add(block, null); }
protected override void TraverseBlock(Block block) { Func<Type, Type> safeType = t => t.IsRectMdArray() ? typeof(Object) : t; block.Locals.ForEach(l => locals.Add(l, il.DeclareLocal(safeType(l.Type.AssertNotNull())))); block.ForEach(Traverse); }
protected override void TraverseBlock(Block block) { block.ForEach(stmt => _ptx.emit(stmt)); }