private void Build(DWhile node, Hints hints, CompilerContext ctx) { ctx = new CompilerContext(ctx) { BlockSkip = cw.DefineLabel(), BlockExit = cw.DefineLabel(), BlockBreakExit = cw.DefineLabel() }; var iter = cw.DefineLabel(); hints = hints.Remove(Last); var nh = hints.Has(Push) ? hints.Remove(Push).Append(ExpectPush) : hints; if (node.DoWhile) { Build(node.Body, nh, ctx); } cw.MarkLabel(iter); Build(node.Condition, hints.Append(Push), ctx); cw.Brfalse(ctx.BlockExit); Build(node.Body, nh, ctx); cw.MarkLabel(ctx.BlockSkip); cw.Br(iter); cw.MarkLabel(ctx.BlockExit); PushIf(hints); AddLinePragma(node); cw.MarkLabel(ctx.BlockBreakExit); cw.Nop(); }
private void Build(DWhile node, Hints hints, CompilerContext ctx) { ctx = new(ctx) { BlockSkip = cw.DefineLabel(), BlockExit = cw.DefineLabel(), BlockBreakExit = cw.DefineLabel() }; StartScope(ScopeKind.Loop, node.Location); var iter = cw.DefineLabel(); hints = hints.Remove(Last); var nh = hints.Remove(Push); if (node.DoWhile) { Build(node.Body, nh, ctx); } cw.MarkLabel(iter); Build(node.Condition, hints.Append(Push), ctx); cw.Brfalse(ctx.BlockExit); Build(node.Body, nh, ctx); cw.MarkLabel(ctx.BlockSkip); cw.Br(iter); cw.MarkLabel(ctx.BlockExit); cw.PushNil(); AddLinePragma(node); cw.MarkLabel(ctx.BlockBreakExit); PopIf(hints); cw.Nop(); EndScope(); }