protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement == null) { // if <condition> // <then> // // ----> // // gotoFalse <condition> end // <then> // end: // var endLabel = GenerateLabel(); var gotoFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, false); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(gotoFalse, node.ThenStatement, endLabelStatement)); 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 gotoFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, false); var gotoEndStatement = new BoundGotoStatement(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoFalse, node.ThenStatement, gotoEndStatement, elseLabelStatement, node.ElseStatement, endLabelStatement )); return(RewriteStatement(result)); } }
protected override BoundStatement RewriteConditionalStatement(BoundConditionalStatement node) { if (node.ElseStatement is null) { // if <condition> <then> // --- to ---> // { // gotoFalse <condition> end // <then> // end: // } var endLabel = GenerateLabel("end"); var gotoFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, false); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement( gotoFalse, node.ThenStatement, endLabelStatement); return(RewriteStatement(result)); } else { // if <condition> <then> else <else> // --- to ---> // { // gotoFalse <condition> else // <then> // goto end // else: // <else> // end: // } var endLabel = GenerateLabel("end"); var elseLabel = GenerateLabel("else"); var gotoFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, false); var gotoEnd = new BoundGotoStatement(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement( gotoFalse, node.ThenStatement, gotoEnd, elseLabelStatement, node.ElseStatement, endLabelStatement); return(RewriteStatement(result)); } }
internal bool Parse(BoundGotoStatement boundGotoStatement) { if (boundGotoStatement == null) { throw new ArgumentNullException(); } if (boundGotoStatement.Label.NeedsLabel("continue")) { return(true); } return(false); }
internal bool Parse(BoundGotoStatement boundGotoStatement) { if (boundGotoStatement == null) { throw new ArgumentNullException(); } if (boundGotoStatement.Label.Name.StartsWith("<break")) { return(true); } return(false); }
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))); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { /* * gotoIfFalse <condition> end * <Then> * end: * * gotoIfFalse <condition> else * <Then> * goto end * else: * <Else> * end: */ BoundBlockStatement result; if (node.ElseClause is null) { result = Create(); } else { result = CreateWithElse(); } return(RewriteStatement(result)); BoundBlockStatement Create() { var endLabelStatement = new BoundLabelStatement(GenerateLabel()); var gotoIfFalseStatement = new BoundConditionalGotoStatement(endLabelStatement.Label, node.Condition, false); return(new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(gotoIfFalseStatement, node.Statement, endLabelStatement))); } BoundBlockStatement CreateWithElse() { var elseLabelStatement = new BoundLabelStatement(GenerateLabel()); var endLabelStatement = new BoundLabelStatement(GenerateLabel()); var gotoIfFalseStatement = new BoundConditionalGotoStatement(elseLabelStatement.Label, node.Condition, false); var gotoEndStatement = new BoundGotoStatement(endLabelStatement.Label); var statements = ImmutableArray.Create <BoundStatement>(gotoIfFalseStatement, node.Statement, gotoEndStatement, elseLabelStatement, node.ElseClause, endLabelStatement); return(new BoundBlockStatement(statements)); } }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { /* * check: * gotoIfFalse <condition> end * <statement> * goto check * end: */ var checkLabelStatement = new BoundLabelStatement(GenerateLabel()); var endLabelStatement = new BoundLabelStatement(GenerateLabel()); var gotoIfFalseStatement = new BoundConditionalGotoStatement(endLabelStatement.Label, node.Condition, false); var gotoCheckStatement = new BoundGotoStatement(checkLabelStatement.Label); var statements = ImmutableArray.Create <BoundStatement>(checkLabelStatement, gotoIfFalseStatement, node.Statement, gotoCheckStatement, endLabelStatement); var result = new BoundBlockStatement(statements); return(RewriteStatement(result)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { var bodyLabel = GenerateLabel(); var gotoContinue = new BoundGotoStatement(node.ContinueLabel); var bodyLabelStatement = new BoundLabelStatement(bodyLabel); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var gotoTrue = new BoundConditionalGotoStatement(bodyLabel, node.Condition); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoContinue, bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement )); return(RewriteStatement(result)); }
internal void Parse(BoundGotoStatement boundGotoStatement) { if (boundGotoStatement == null) { throw new ArgumentNullException(); } var sourceLabelSymbol = boundGotoStatement.Label as SourceLabelSymbol; if (sourceLabelSymbol != null) { var switchLabel = new SwitchLabel(); switchLabel.Parse(sourceLabelSymbol); this.Label = switchLabel; } else { var label = new Label(); label.Parse(boundGotoStatement.Label); this.Label = label; } }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // goto check: // continue: // <body> // check: // gotoTrue condition continue: // end: // ------------------------------------------------------- // later try out //- begin //- gotoFalse <condition> end //- <body> //- goto begin //- end var endLabel = GenerateLabel(); var checkLabel = GenerateLabel(); var continueLabel = GenerateLabel(); var gotoCheck = new BoundGotoStatement(checkLabel); var gotoTrue = new BoundConditionalGotoStatement(continueLabel, node.Condition); var continueLabelStatement = new BoundLabelStatement(continueLabel); var checkLabelStatement = new BoundLabelStatement(checkLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement( ImmutableArray.Create <BoundStatement>( gotoCheck, continueLabelStatement, node.Body, checkLabelStatement, gotoTrue, endLabelStatement)); return(RewriteStatement(result)); }
protected override BoundStatement RewriteTryCatchStatement(BoundTryCatchStatement node) { // try // <tryBody> // catch // <catchBody> // // ----> // // beginTry error // <tryBody> // endTry // goto end // error: // <catchBody> // end: var errorLabel = GenerateLabel(); var endLabel = GenerateLabel(); var beginTryStatement = new BoundBeginTryStatement(errorLabel); var endTryStatement = new BoundEndTryStatement(); var gotoEndStatement = new BoundGotoStatement(endLabel); var errorLabelStatement = new BoundLabelStatement(errorLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( beginTryStatement, node.TryBody, endTryStatement, gotoEndStatement, errorLabelStatement, node.CatchBody, endLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { BoundLabel bodyLabel = GenerateLabel(); BoundLabel endLabel = new BoundLabel("End"); BoundGotoStatement gotoContinueLabel = new BoundGotoStatement(node.ContinueLabel); BoundLabelStatement bodyLabelStatement = new BoundLabelStatement(bodyLabel); BoundLabelStatement continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); BoundConditionalGotoStatement gotoTrue = new BoundConditionalGotoStatement(bodyLabel, node.Condition, true); BoundLabelStatement breakLabelStatement = new BoundLabelStatement(node.BreakLabel); BoundLabelStatement endLabelStatement = new BoundLabelStatement(endLabel); BoundBlockStatement result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoContinueLabel, bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement, endLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // while <condition> // <bode> // // -----> // // goto check // continue: // <body> // check: // gotoTrue <condition> continue // end: // var continueLabel = GenerateLabel(); var checkLabel = GenerateLabel(); var endLabel = GenerateLabel(); var gotoCheck = new BoundGotoStatement(checkLabel); var continueLabelStatement = new BoundLabelStatement(continueLabel); var checkLabelStatement = new BoundLabelStatement(checkLabel); var gotoTrue = new BoundConditionalGotoStatement(continueLabel, node.Condition); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoCheck, continueLabelStatement, node.Body, checkLabelStatement, gotoTrue, endLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement == null) { var endLabel = GenerateLabel(); var gotoFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, true); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(gotoFalse, node.Statement, endLabelStatement)); return(RewriteStatement(result)); } else { var elseLabel = GenerateLabel(); var endLabel = GenerateLabel(); var gotoFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, true); var gotoEnd = new BoundGotoStatement(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoFalse, node.Statement, gotoEnd, elseLabelStatement, node.ElseStatement, endLabelStatement)); return(RewriteStatement(result)); } }
private static void WriteBoundGotoStatement(this IndentedTextWriter writer, BoundGotoStatement node) { writer.WriteMagentaKeyword("goto"); writer.WriteSpace(); writer.ColorWrite(node.Label.Identifier); }
public virtual void VisitGotoStatement(BoundGotoStatement node) => this.DefaultVisit(node);
public object EvaluateStatement(BoundBlockStatement body) { var labelToIndex = new Dictionary <BoundLabel, int>(); for (int i = 0; i < body.Statements.Length; i++) { if (body.Statements[i] is BoundLabelStatement l) { labelToIndex.Add(l.Label, i + 1); } } int index = 0; while (index < body.Statements.Length) { var s = body.Statements[index]; switch (s.Kind) { case BoundNodeKind.VariableDeclaration: EvaluateVariableDeclaration((BoundVariableDeclaration)s); index++; break; case BoundNodeKind.ExpressionStatement: EvaluateExpressionStatement((BoundExpressionStatement)s); index++; break; case BoundNodeKind.GotoStatement: BoundGotoStatement gs = (BoundGotoStatement)s; index = labelToIndex[gs.Label]; break; case BoundNodeKind.ConditionalGotoStatement: var cgs = (BoundConditionalGotoStatement)s; var condition = (bool)EvaluateExpression(cgs.Condition); if (condition == cgs.JumpIfTrue) { index = labelToIndex[cgs.Label]; } else { index++; } break; case BoundNodeKind.LabelStatement: index++; break; case BoundNodeKind.ReturnStatement: var rs = (BoundReturnStatement)s; _lastValue = rs.Expression == null ? null : EvaluateExpression(rs.Expression); return(_lastValue); default: throw new Exception($"Unexpected node {s.Kind}"); } } return(_lastValue); }
public override BoundNode VisitGotoStatement(BoundGotoStatement node) { CheckCanMergeWithParent(node.Label); return(base.VisitGotoStatement(node)); }
private BoundStatement RewriteForStatement( SyntaxNode syntax, ReadOnlyArray <LocalSymbol> locals, BoundStatement rewrittenInitializer, BoundExpression rewrittenCondition, SyntaxNodeOrToken conditionSyntax, BoundStatement rewrittenIncrement, BoundStatement rewrittenBody, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors) { var startLabel = new GeneratedLabelSymbol("start"); var endLabel = new GeneratedLabelSymbol("end"); // for (initializer; condition; increment) // body; // // becomes the following (with // block added for locals) // // { // initializer; // goto end; // start: // body; // continue: // increment; // end: // GotoIfTrue condition start; // break: // } // initializer; // goto end; var statementBuilder = ArrayBuilder <BoundStatement> .GetInstance(); if (rewrittenInitializer != null) { statementBuilder.Add(rewrittenInitializer); } //mark the initial jump as hidden. //We do it to tell that this is not a part of previous 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 var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel)); statementBuilder.Add(gotoEnd); // start: // body; statementBuilder.Add(new BoundLabelStatement(syntax, startLabel)); Debug.Assert(rewrittenBody != null); statementBuilder.Add(rewrittenBody); // continue: // increment; statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel)); if (rewrittenIncrement != null) { statementBuilder.Add(rewrittenIncrement); } // end: // GotoIfTrue condition start; statementBuilder.Add(new BoundLabelStatement(syntax, endLabel)); BoundStatement branchBack = null; if (rewrittenCondition != null) { branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel); } else { branchBack = new BoundGotoStatement(syntax, startLabel); } if (this.generateDebugInfo) { if (conditionSyntax.IsToken) { branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span); } else { //if there is no condition, make this a hidden point so that //it does not count as a part of previous statement branchBack = new BoundSequencePoint(conditionSyntax.AsNode(), branchBack); } } statementBuilder.Add(branchBack); // break: statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel)); var statements = statementBuilder.ToReadOnlyAndFree(); return(new BoundBlock(syntax, locals, statements, hasErrors)); }
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)); }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { /* * * for <decl>, <condition>, <increment> { * <body> * } * * * -----> * * { * <decl> * while <condition>{ * <body> * continue: * <increment> * } * break: * } * * * -----> * * * <decl> * goto check * body: * <body> * continue: * <increment> * check: * goto body if <condtiton> * break: */ var decl = node.VariableDeclaration; var increment = new BoundExpressionStatement(node.Increment, node.IsValid, true); var body = node.Body; var condition = node.Condition; var bodyLabel = CreateLabel(); var continueLabel = node.ContinueLabel; var checkLabel = CreateLabel(); var breakLabel = node.BreakLabel; var bodyLabelStmt = new BoundLabelStatement(bodyLabel, node.IsValid); var continueLabelStmt = new BoundLabelStatement(continueLabel, node.IsValid); var checkLabelStmt = new BoundLabelStatement(checkLabel, node.IsValid); var breakLabelStmt = new BoundLabelStatement(breakLabel, node.IsValid); var gotoCheck = new BoundGotoStatement(checkLabel, node.IsValid); var gotoTrueBody = new BoundConditionalGotoStatement(bodyLabel, node.Condition, jumpIfFalse: false, node.IsValid); var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( decl, gotoCheck, bodyLabelStmt, body, continueLabelStmt, increment, checkLabelStmt, gotoTrueBody, breakLabelStmt ), node.IsValid); return(RewriteStatement(res)); }
/// <inheritdoc/> protected override BoundStatement RewriteForEllipsisStatement(BoundForEllipsisStatement node) { // for <var> := <lower> ... <upper> // <body> // // ----> // // { // var <var> = <lower> // const upperBound = <upper> // var step = 1 // if <var> greaterthan upperBound { // step = -1 // } // goto start // body: // <body> // continue: // <var> = <var> + step // start: // gotoTrue ((step > 0 && lower < upper) || (step < 0 && lower > upper)) body // break: // } var variableDeclaration = new BoundVariableDeclaration(node.Variable, node.LowerBound); var upperBoundSymbol = new LocalVariableSymbol("upperBound", isReadOnly: true, type: TypeSymbol.Int); var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound); var stepBoundSymbol = new LocalVariableSymbol("step", isReadOnly: false, type: TypeSymbol.Int); var stepBoundDeclaration = new BoundVariableDeclaration( variable: stepBoundSymbol, initializer: new BoundLiteralExpression(1)); var variableExpression = new BoundVariableExpression(node.Variable); var upperBoundExpression = new BoundVariableExpression(upperBoundSymbol); var stepBoundExpression = new BoundVariableExpression(stepBoundSymbol); var ifLowerIsGreaterThanUpperExpression = new BoundBinaryExpression( left: variableExpression, op: BoundBinaryOperator.Bind(SyntaxKind.GreaterToken, TypeSymbol.Int, TypeSymbol.Int), right: upperBoundExpression); var stepBoundAssingment = new BoundExpressionStatement( expression: new BoundAssignmentExpression( variable: stepBoundSymbol, expression: new BoundLiteralExpression(-1))); var ifLowerIsGreaterThanUpperIfStatement = new BoundIfStatement( condition: ifLowerIsGreaterThanUpperExpression, thenStatement: stepBoundAssingment, elseStatement: null); var startLabel = GenerateLabel(); var gotoStart = new BoundGotoStatement(startLabel); var bodyLabel = GenerateLabel(); var bodyLabelStatement = new BoundLabelStatement(bodyLabel); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var increment = new BoundExpressionStatement( expression: new BoundAssignmentExpression( variable: node.Variable, expression: new BoundBinaryExpression( left: variableExpression, op: BoundBinaryOperator.Bind(SyntaxKind.PlusToken, TypeSymbol.Int, TypeSymbol.Int), right: stepBoundExpression))); var startLabelStatement = new BoundLabelStatement(startLabel); var zeroLiteralExpression = new BoundLiteralExpression(0); var stepGreaterThanZeroExpression = new BoundBinaryExpression( left: stepBoundExpression, op: BoundBinaryOperator.Bind(SyntaxKind.GreaterToken, TypeSymbol.Int, TypeSymbol.Int), right: zeroLiteralExpression); var lowerLessThanUpperExpression = new BoundBinaryExpression( left: variableExpression, op: BoundBinaryOperator.Bind(SyntaxKind.LessToken, TypeSymbol.Int, TypeSymbol.Int), right: upperBoundExpression); var positiveStepAndLowerLessThanUpper = new BoundBinaryExpression( left: stepGreaterThanZeroExpression, op: BoundBinaryOperator.Bind(SyntaxKind.AmpersandAmpersandToken, TypeSymbol.Bool, TypeSymbol.Bool), right: lowerLessThanUpperExpression); var stepLessThanZeroExpression = new BoundBinaryExpression( left: stepBoundExpression, op: BoundBinaryOperator.Bind(SyntaxKind.LessToken, TypeSymbol.Int, TypeSymbol.Int), right: zeroLiteralExpression); var lowerGreaterThanUpperExpression = new BoundBinaryExpression( left: variableExpression, op: BoundBinaryOperator.Bind(SyntaxKind.GreaterToken, TypeSymbol.Int, TypeSymbol.Int), right: upperBoundExpression); var negativeStepAndLowerGreaterThanUpper = new BoundBinaryExpression( left: stepLessThanZeroExpression, op: BoundBinaryOperator.Bind(SyntaxKind.AmpersandAmpersandToken, TypeSymbol.Bool, TypeSymbol.Bool), right: lowerGreaterThanUpperExpression); var condition = new BoundBinaryExpression( positiveStepAndLowerLessThanUpper, BoundBinaryOperator.Bind(SyntaxKind.PipePipeToken, TypeSymbol.Bool, TypeSymbol.Bool), negativeStepAndLowerGreaterThanUpper); var gotoTrue = new BoundConditionalGotoStatement(bodyLabel, condition, jumpIfTrue: true); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( variableDeclaration, upperBoundDeclaration, stepBoundDeclaration, ifLowerIsGreaterThanUpperIfStatement, gotoStart, bodyLabelStatement, node.Body, continueLabelStatement, increment, startLabelStatement, gotoTrue, breakLabelStatement)); return(RewriteStatement(result)); }
private void EmitGotoStatement(BoundGotoStatement boundGotoStatement) { _builder.EmitBranch(ILOpCode.Br, boundGotoStatement.Label); }
public override object VisitGotoStatement(BoundGotoStatement node, object arg) { pendingBranches.Add(new PendingBranch(node, this.state)); SetUnreachable(); return(null); }
public override void VisitGotoStatement(BoundGotoStatement node) { _writer.WriteKeyword("goto "); _writer.WriteIdentifier(node.BoundLabel.Name); _writer.WriteLine(); }
/// <summary> /// Subclasses override this if they want to take special actions on processing a goto /// statement, when both the jump and the label have been located. /// </summary> /// <param name="pending"></param> /// <param name="gotoStmt"></param> /// <param name="labelStmt"></param> protected virtual void NoteBranch(PendingBranch pending, BoundGotoStatement gotoStmt, BoundLabelStatement labelStmt) { }
public override BoundNode VisitGotoStatement(BoundGotoStatement node) { var labelClone = GetLabelClone(node.Label); // expressions do not contain labels or branches BoundExpression caseExpressionOpt = node.CaseExpressionOpt; // expressions do not contain labels or branches BoundLabel labelExpressionOpt = node.LabelExpressionOpt; return node.Update(labelClone, caseExpressionOpt, labelExpressionOpt); }
private BoundStatement RewriteForStatement( SyntaxNode syntax, ReadOnlyArray<LocalSymbol> locals, BoundStatement rewrittenInitializer, BoundExpression rewrittenCondition, SyntaxNodeOrToken conditionSyntax, BoundStatement rewrittenIncrement, BoundStatement rewrittenBody, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors) { var startLabel = new GeneratedLabelSymbol("start"); var endLabel = new GeneratedLabelSymbol("end"); // for (initializer; condition; increment) // body; // // becomes the following (with // block added for locals) // // { // initializer; // goto end; // start: // body; // continue: // increment; // end: // GotoIfTrue condition start; // break: // } // initializer; // goto end; var statementBuilder = ArrayBuilder<BoundStatement>.GetInstance(); if (rewrittenInitializer != null) { statementBuilder.Add(rewrittenInitializer); } //mark the initial jump as hidden. //We do it to tell that this is not a part of previous 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 var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel)); statementBuilder.Add(gotoEnd); // start: // body; statementBuilder.Add(new BoundLabelStatement(syntax, startLabel)); Debug.Assert(rewrittenBody != null); statementBuilder.Add(rewrittenBody); // continue: // increment; statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel)); if (rewrittenIncrement != null) { statementBuilder.Add(rewrittenIncrement); } // end: // GotoIfTrue condition start; statementBuilder.Add(new BoundLabelStatement(syntax, endLabel)); BoundStatement branchBack = null; if (rewrittenCondition != null) { branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel); } else { branchBack = new BoundGotoStatement(syntax, startLabel); } if (this.generateDebugInfo) { if (conditionSyntax.IsToken) { branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span); } else { //if there is no condition, make this a hidden point so that //it does not count as a part of previous statement branchBack = new BoundSequencePoint(conditionSyntax.AsNode(), branchBack); } } statementBuilder.Add(branchBack); // break: statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel)); var statements = statementBuilder.ToReadOnlyAndFree(); return new BoundBlock(syntax, locals, statements, hasErrors); }
public override BoundNode VisitGotoStatement(BoundGotoStatement node) { Debug.Assert(node.CaseExpressionOpt == null, "we should not have label expressions at this stage"); var result = base.VisitGotoStatement(node); RecordBranch(node.Label); return result; }
private void EmitGotoStatement(ILProcessor ilProcessor, BoundGotoStatement node) { throw new NotImplementedException(); }