protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node) { // do // <body> // while <condition> // // -----> // // body: // <body> // continue: // gotoTrue <condition> body // break: var bodyLabel = GenerateLabel(); var result = BoundNodeFactory.Block(node.Syntax, BoundNodeFactory.Label(node.Syntax, bodyLabel), node.Body, BoundNodeFactory.Label(node.Syntax, node.ContinueLabel), BoundNodeFactory.GotoTrue(node.Syntax, bodyLabel, node.Condition), BoundNodeFactory.Label(node.Syntax, node.BreakLabel) ); return(RewriteStatement(result)); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement == null) { // if <condition> // <then> // // ----> // // gotoFalse <condition> end // <then> // end: var endLabel = GenerateLabel(); var result = BoundNodeFactory.Block(node.Syntax, BoundNodeFactory.GotoFalse(node.Syntax, endLabel, node.Condition), node.ThenStatement, BoundNodeFactory.Label(node.Syntax, endLabel) ); return(RewriteStatement(result)); } else { // if <condition> // <then> // else // <else> // // ----> // // gotoFalse <condition> else // <then> // goto end // else: // <else> // end: var elseLabel = GenerateLabel(); var endLabel = GenerateLabel(); var result = BoundNodeFactory.Block(node.Syntax, BoundNodeFactory.GotoFalse(node.Syntax, elseLabel, node.Condition), node.ThenStatement, BoundNodeFactory.Goto(node.Syntax, endLabel), BoundNodeFactory.Label(node.Syntax, elseLabel), node.ElseStatement, BoundNodeFactory.Label(node.Syntax, endLabel) ); return(RewriteStatement(result)); } }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { // for <var> = <lower> to <upper> // <body> // // ----> // // { // var <var> = <lower> // let upperBound = <upper> // while (<var> <= upperBound) // { // <body> // continue: // <var> = <var> + 1 // } // } var lowerBound = BoundNodeFactory.VariableDeclaration(node.Syntax, node.Variable, node.LowerBound); var upperBound = BoundNodeFactory.ConstantDeclaration(node.Syntax, "upperBound", node.UpperBound); var result = BoundNodeFactory.Block(node.Syntax, lowerBound, upperBound, BoundNodeFactory.While(node.Syntax, BoundNodeFactory.LessOrEqual( node.Syntax, BoundNodeFactory.Variable(node.Syntax, lowerBound), BoundNodeFactory.Variable(node.Syntax, upperBound) ), BoundNodeFactory.Block( node.Syntax, node.Body, BoundNodeFactory.Label(node.Syntax, node.ContinueLabel), BoundNodeFactory.Increment( node.Syntax, BoundNodeFactory.Variable(node.Syntax, lowerBound) ) ), node.BreakLabel, continueLabel: GenerateLabel())); return(RewriteStatement(result)); }