Exemplo n.º 1
0
        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));
            }
        }
Exemplo n.º 2
0
        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));
            }
        }
Exemplo n.º 3
0
        internal bool Parse(BoundGotoStatement boundGotoStatement)
        {
            if (boundGotoStatement == null)
            {
                throw new ArgumentNullException();
            }

            if (boundGotoStatement.Label.NeedsLabel("continue"))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 4
0
        internal bool Parse(BoundGotoStatement boundGotoStatement)
        {
            if (boundGotoStatement == null)
            {
                throw new ArgumentNullException();
            }

            if (boundGotoStatement.Label.Name.StartsWith("<break"))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 5
0
        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)));
        }
Exemplo n.º 6
0
        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));
            }
        }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 8
0
        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));
        }
Exemplo n.º 9
0
        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;
            }
        }
Exemplo n.º 10
0
        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));
        }
Exemplo n.º 11
0
        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));
        }
Exemplo n.º 12
0
        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));
        }
Exemplo n.º 13
0
        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));
        }
Exemplo n.º 14
0
        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));
            }
        }
Exemplo n.º 15
0
 private static void WriteBoundGotoStatement(this IndentedTextWriter writer, BoundGotoStatement node)
 {
     writer.WriteMagentaKeyword("goto");
     writer.WriteSpace();
     writer.ColorWrite(node.Label.Identifier);
 }
Exemplo n.º 16
0
 public virtual void VisitGotoStatement(BoundGotoStatement node) =>
 this.DefaultVisit(node);
Exemplo n.º 17
0
        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);
        }
Exemplo n.º 18
0
                public override BoundNode VisitGotoStatement(BoundGotoStatement node)
                {
                    CheckCanMergeWithParent(node.Label);

                    return(base.VisitGotoStatement(node));
                }
Exemplo n.º 19
0
        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));
        }
Exemplo n.º 20
0
        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));
        }
Exemplo n.º 21
0
        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));
        }
Exemplo n.º 22
0
        /// <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));
        }
Exemplo n.º 23
0
 private void EmitGotoStatement(BoundGotoStatement boundGotoStatement)
 {
     _builder.EmitBranch(ILOpCode.Br, boundGotoStatement.Label);
 }
Exemplo n.º 24
0
 public override object VisitGotoStatement(BoundGotoStatement node, object arg)
 {
     pendingBranches.Add(new PendingBranch(node, this.state));
     SetUnreachable();
     return(null);
 }
Exemplo n.º 25
0
 public override void VisitGotoStatement(BoundGotoStatement node)
 {
     _writer.WriteKeyword("goto ");
     _writer.WriteIdentifier(node.BoundLabel.Name);
     _writer.WriteLine();
 }
Exemplo n.º 26
0
 /// <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)
 {
 }
Exemplo n.º 27
0
 /// <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)
 {
 }
Exemplo n.º 28
0
            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);
            }
Exemplo n.º 29
0
        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);
        }
Exemplo n.º 30
0
        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;
        }
Exemplo n.º 31
0
 private void EmitGotoStatement(ILProcessor ilProcessor, BoundGotoStatement node)
 {
     throw new NotImplementedException();
 }