// collect locals into provided scope // leave initializers in the tree if there are any public override BoundNode VisitMultipleLocalDeclarations(BoundMultipleLocalDeclarations node) { ArrayBuilder <BoundStatement> inits = null; foreach (var decl in node.LocalDeclarations) { var init = VisitLocalDeclaration(decl); if (init != null) { if (inits == null) { inits = ArrayBuilder <BoundStatement> .GetInstance(); } inits.Add((BoundStatement)init); } } if (inits != null) { return(BoundStatementList.Synthesized(node.Syntax, node.HasErrors, inits.ToReadOnlyAndFree())); } else { // no initializers return(null); // TODO: but what if hasErrors? Have we lost that? } }
private static BoundStatement RewriteIfStatement( SyntaxNode syntax, BoundExpression rewrittenCondition, BoundStatement rewrittenConsequence, BoundStatement rewrittenAlternativeOpt, bool hasErrors) { var afterif = new GeneratedLabelSymbol("afterif"); // if (condition) // consequence; // // becomes // // GotoIfFalse condition afterif; // consequence; // afterif: if (rewrittenAlternativeOpt == null) { return(BoundStatementList.Synthesized(syntax, new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, afterif), rewrittenConsequence, new BoundLabelStatement(syntax, afterif))); } // if (condition) // consequence; // else // alternative // // becomes // // GotoIfFalse condition alt; // consequence // goto afterif; // alt: // alternative; // afterif: var alt = new GeneratedLabelSymbol("alternative"); return(BoundStatementList.Synthesized(syntax, hasErrors, new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, alt), rewrittenConsequence, new BoundGotoStatement(syntax, afterif), new BoundLabelStatement(syntax, alt), rewrittenAlternativeOpt, new BoundLabelStatement(syntax, afterif))); }
private BoundStatement RewriteWhileStatement( SyntaxNode syntax, BoundExpression rewrittenCondition, TextSpan conditionSequencePointSpan, BoundStatement rewrittenBody, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors) { var startLabel = new GeneratedLabelSymbol("start"); BoundStatement ifConditionGotoStart = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel); if (this.generateDebugInfo) { ifConditionGotoStart = new BoundSequencePointWithSpan(syntax, ifConditionGotoStart, conditionSequencePointSpan); } // while (condition) // body; // // becomes // // goto continue; // start: // body // continue: // GotoIfTrue condition start; // break: BoundStatement gotoContinue = new BoundGotoStatement(syntax, continueLabel); if (this.generateDebugInfo) { //mark the initial jump as hidden. //We do it to tell that this is not a part of previou statement. //This jump may be a target of another jump (for example if loops are nested) and that will make //impression of the previous statement being re-executed gotoContinue = new BoundSequencePoint(null, gotoContinue); } return(BoundStatementList.Synthesized(syntax, hasErrors, gotoContinue, new BoundLabelStatement(syntax, startLabel), rewrittenBody, new BoundLabelStatement(syntax, continueLabel), ifConditionGotoStart, new BoundLabelStatement(syntax, breakLabel))); }
public override BoundNode VisitLabeledStatement(BoundLabeledStatement node) { Debug.Assert(node != null); var rewrittenBody = (BoundStatement)Visit(node.Body); var labelStatement = new BoundLabelStatement(node.Syntax, node.Label); if (rewrittenBody == null) { // Body may be null if the body has no associated IL // (declaration with no initializer for instance.) return(labelStatement); } return(BoundStatementList.Synthesized(node.Syntax, labelStatement, rewrittenBody)); }
public override BoundNode VisitDoStatement(BoundDoStatement node) { Debug.Assert(node != null); var rewrittenCondition = (BoundExpression)Visit(node.Condition); var rewrittenBody = (BoundStatement)Visit(node.Body); var startLabel = new GeneratedLabelSymbol("start"); var syntax = node.Syntax; BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, rewrittenCondition, true, startLabel); if (this.generateDebugInfo) { var doSyntax = (DoStatementSyntax)syntax; var span = TextSpan.FromBounds( doSyntax.WhileKeyword.Span.Start, doSyntax.SemicolonToken.Span.End); ifConditionGotoStart = new BoundSequencePointWithSpan(doSyntax, ifConditionGotoStart, span); } // do // body // while (condition); // // becomes // // start: // body // continue: // sequence point // GotoIfTrue condition start; // break: return(BoundStatementList.Synthesized(syntax, node.HasErrors, new BoundLabelStatement(syntax, startLabel), rewrittenBody, new BoundLabelStatement(syntax, node.ContinueLabel), ifConditionGotoStart, new BoundLabelStatement(syntax, node.BreakLabel))); }