private IEnumerable <Instruction> _ProcessLoopBody(LoopBodyTransformer bodyTransformer, Label continueLabel, Label breakLabel) { var oldEnclosing = _enclosingLoop; _enclosingLoop = new LoopDescriptor(continueLabel, breakLabel); // ToArray (or any form of materialization) is important to ensure that the body is actually processed at this place. var result = bodyTransformer().ToArray(); _enclosingLoop = oldEnclosing; return(result); }
public override IEnumerable <Instruction> VisitDoStatement(DoStatementSyntax node) { LoopBodyTransformer bodyTransformer = () => node.Statement?.Accept(this) ?? Enumerable.Empty <Instruction>(); var loopEntry = new Label(); var loopExit = new Label(); var continueLabel = new Label(); var transformed = new List <Instruction>(); transformed.Add(loopEntry); transformed.AddRange(_ProcessLoopBody(bodyTransformer, continueLabel, loopExit)); transformed.Add(continueLabel); transformed.Add(new ConditionalJump(_expressionFactory.Create(node.Condition), loopEntry)); transformed.Add(loopExit); return(transformed); }
private IEnumerable <Instruction> _CreateLoop(ExpressionSyntax condition, LoopBodyTransformer bodyTransformer, Label continueLabel) { var loopEntry = new Label(); var loopExit = new Label(); var loopBody = new Label(); continueLabel = continueLabel ?? loopEntry; var transformed = new List <Instruction>(); transformed.Add(loopEntry); transformed.Add(condition == null ? (Instruction) new Jump(loopBody) : new ConditionalJump(_expressionFactory.Create(condition), loopBody)); transformed.Add(new Jump(loopExit)); transformed.Add(loopBody); transformed.AddRange(_ProcessLoopBody(bodyTransformer, continueLabel, loopExit)); transformed.Add(new Jump(loopEntry)); transformed.Add(loopExit); return(transformed); }
public override IEnumerable <Instruction> VisitForStatement(ForStatementSyntax node) { var transformed = new List <Instruction>(); if (node.Declaration != null) { transformed.AddRange(node.Declaration.Accept(this)); } transformed.AddRange(node.Initializers.SelectMany(initializer => initializer.Accept(this))); var continueLabel = new Label(); LoopBodyTransformer bodyTransformer = () => { var body = new List <Instruction>(); body.AddRange(node.Statement.Accept(this)); body.Add(continueLabel); body.AddRange(node.Incrementors.SelectMany(incrementor => incrementor.Accept(this))); return(body); }; transformed.AddRange(_CreateLoop(node.Condition, bodyTransformer, continueLabel)); return(transformed); }
public override IEnumerable <Instruction> VisitWhileStatement(WhileStatementSyntax node) { LoopBodyTransformer bodyTransformer = () => node.Statement?.Accept(this) ?? Enumerable.Empty <Instruction>(); return(_CreateLoop(node.Condition, bodyTransformer, null)); }