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 BoundExpression RewriteCompoundAssignmentExpression(BoundCompoundAssignmentExpression node) { var newNode = (BoundCompoundAssignmentExpression)base.RewriteCompoundAssignmentExpression(node); // a <op>= b // // ----> // // a = (a <op> b) return(BoundNodeFactory.Assignment(newNode.Syntax, newNode.Variable, BoundNodeFactory.Binary(newNode.Syntax, BoundNodeFactory.Variable(newNode.Syntax, newNode.Variable), newNode.Op, newNode.Expression))); }
protected override BoundExpression RewriteCompoundFieldAssignmentExpression(BoundCompoundFieldAssignmentExpression node) { var newNode = (BoundCompoundFieldAssignmentExpression)base.RewriteCompoundFieldAssignmentExpression(node); // a.f <op>= b // // ----> // // a.f = (a.f <op> b) return(BoundNodeFactory.Assignment(newNode.Syntax, newNode.StructInstance, newNode.StructMember, BoundNodeFactory.Binary(newNode.Syntax, BoundNodeFactory.Field(newNode.Syntax, newNode.StructInstance, newNode.StructMember), newNode.Op, newNode.Expression) )); }
protected override BoundStatement RewriteConditionalGotoStatement(BoundConditionalGotoStatement node) { if (node.Condition.ConstantValue != null) { var condition = (bool)node.Condition.ConstantValue.Value !; condition = node.JumpIfTrue ? condition : !condition; if (condition) { return(RewriteStatement(BoundNodeFactory.Goto(node.Syntax, node.Label))); } else { return(RewriteStatement(BoundNodeFactory.Nop(node.Syntax))); } } return(base.RewriteConditionalGotoStatement(node)); }
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)); }