Esempio n. 1
0
        protected virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node)
        {
            ImmutableArray <BoundStatement> .Builder builder = null;

            for (var i = 0; i < node.Statements.Length; i++)
            {
                var oldStatement = node.Statements[i];
                var newStatement = RewriteStatement(oldStatement);

                if (newStatement != oldStatement)
                {
                    if (builder == null)
                    {
                        builder = ImmutableArray.CreateBuilder <BoundStatement>(node.Statements.Length);

                        for (var j = 0; j < i; j++)
                        {
                            builder.Add(node.Statements[j]);
                        }
                    }
                }

                if (builder != null)
                {
                    builder.Add(newStatement);
                }
            }

            if (builder == null)
            {
                return(node);
            }

            return(new BoundBlockStatement(builder.MoveToImmutable()));
        }
Esempio n. 2
0
        protected override BoundStatement RewriteIfStatement(BoundIfStatement node)
        {
            if (node.ElseStatement is null)
            {
                var endLabel     = CreateLabel();
                var gotoIfFalse  = new BoundConditionalGotoStatement(endLabel, node.Condition, jumpIfFalse: true, node.IsValid);
                var endLabelStmt = new BoundLabelStatement(endLabel, node.IsValid);
                var res          = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(gotoIfFalse, node.Body, endLabelStmt), node.IsValid);
                return(RewriteStatement(res));
            }
            else
            {
                var elseLabel = CreateLabel();
                var endLabel  = CreateLabel();

                var gotoIfFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, jumpIfFalse: true, node.IsValid);
                var gotoEnd     = new BoundGotoStatement(endLabel, node.IsValid);

                var elseLabelStmt = new BoundLabelStatement(elseLabel, node.IsValid);
                var endLabelStmt  = new BoundLabelStatement(endLabel, node.IsValid);

                var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                      gotoIfFalse,
                                                      node.Body,
                                                      gotoEnd,
                                                      elseLabelStmt,
                                                      node.ElseStatement,
                                                      endLabelStmt
                                                      ), node.IsValid);
                return(RewriteStatement(res));
            }
        }
Esempio n. 3
0
        public Evaluator(BoundBlockStatement root, IDictionary <VariableSymbol, object> variables)
        {
            _root      = root;
            _variables = variables;

            IndexLabels();
        }
Esempio n. 4
0
        protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node)
        {
            // while <condition>
            //    <body>
            //
            // --->
            //
            // goto check
            // continue:
            //    <body>
            // check:
            //    gotoTrue <condition> continue
            // break:
            //

            var checkLabel = GenerateLabel("Check");

            var gotoCheck = new BoundGotoStatement(checkLabel);
            var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel);
            var checkLabelStatement    = new BoundLabelStatement(checkLabel);
            var gotoTrue            = new BoundConditionalGotoStatement(node.ContinueLabel, node.Condition);
            var breakLabelStatement = new BoundLabelStatement(node.BreakLabel);

            var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                     gotoCheck,
                                                     continueLabelStatement,
                                                     node.Body,
                                                     checkLabelStatement,
                                                     gotoTrue,
                                                     breakLabelStatement
                                                     ));

            return(RewriteStatement(result));
        }
Esempio n. 5
0
        protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node)
        {
            // while <condition>
            //      <body>
            //
            // ----->
            //
            // goto continue
            // body:
            // <body>
            // continue:
            // gotoTrue <condition> body
            // break:
            var bodyLabel     = GenerateLabel();
            var continueLabel = node.ContinueLabel;

            var gotoContinue           = new BoundGotoStatement(continueLabel);
            var bodyLabelStatement     = new BoundLabelStatement(bodyLabel);
            var continueLabelStatement = new BoundLabelStatement(continueLabel);
            var gotoTrue            = new BoundConditionalGotoStatement(bodyLabel, node.Condition, false);
            var breakLabelStatement = new BoundLabelStatement(node.BreakLabel);

            var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                     gotoContinue, bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement));

            return(RewriteStatement(result));
        }
Esempio n. 6
0
        protected override BoundStatement RewriteForStatement(BoundForStatement node)
        {
            //For Statements are now all While Statements
            var variableDeclaration   = new BoundVariableDeclaration(node.Variable, node.LowerBound);
            var variableExpression    = new BoundVariableExpression(node.Variable);
            var upperBoundSymbol      = new VariableSymbol("upperBound", true, typeof(int));
            var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound);
            var condition             = new BoundBinaryExpression(
                variableExpression,
                BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualsToken, typeof(int), typeof(int)),
                new BoundVariableExpression(upperBoundSymbol)
                );
            var increment = new BoundExpressionStatement(
                new BoundAssignmentExpression(
                    node.Variable,
                    new BoundBinaryExpression(
                        variableExpression,
                        BoundBinaryOperator.Bind(SyntaxKind.PlusToken, typeof(int), typeof(int)),
                        new BoundLiteralExpression(1)
                        )
                    )
                );
            var whileBody      = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(node.Body, increment));
            var whileStatement = new BoundWhileStatement(condition, whileBody);
            var result         = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                             variableDeclaration,
                                                             upperBoundDeclaration,
                                                             whileStatement
                                                             ));

            return(RewriteStatement(result));
        }
Esempio n. 7
0
        public EvaluationResult Evaluate(Dictionary <VariableSymbol, object> variables)
        {
            ImmutableArray <Diagnostic> diagnostics = SyntaxTree.Diagnostics.Concat(GlobalScope.Diagnostics).ToImmutableArray();

            if (diagnostics.Any())
            {
                return(new EvaluationResult(diagnostics, null));
            }

            BoundProgram program = Binder.BindProgram(GlobalScope);

            string appPath      = Environment.GetCommandLineArgs()[0];
            string appDirectory = Path.GetDirectoryName(appPath);
            string cfgPath      = Path.Combine(appDirectory, "cfg.dot");
            BoundBlockStatement cfgStatement = !program.Statement.Statements.Any() && program.Functions.Any()
                                                  ? program.Functions.Last().Value
                                                  : program.Statement;
            var cfg = ControlFlowGraph.Create(cfgStatement);

            using (StreamWriter streamWriter = new StreamWriter(cfgPath))
                cfg.WriteTo(streamWriter);

            if (program.Diagnostics.Any())
            {
                return(new EvaluationResult(program.Diagnostics.ToImmutableArray(), null));
            }

            Evaluator evaluator = new Evaluator(program, variables);
            object    value     = evaluator.Evaluate();

            return(new EvaluationResult(ImmutableArray <Diagnostic> .Empty, value));
        }
Esempio n. 8
0
        protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node)
        {
            // while <condition> <body>
            // --- to --->
            // {
            // continue:
            // gotoFalse <condition> break
            // <body>
            // goto continue
            // break:
            // }

            var continueLabel = node.ContinueLabel;
            var breakLabel    = node.BreakLabel;

            var continueStatement  = new BoundLabelStatement(continueLabel);
            var gotoFalseStatement = new BoundConditionalGotoStatement(breakLabel, node.Condition, jumpIfTrue: false);
            var gotoContinue       = new BoundGotoStatement(continueLabel);
            var breakStatement     = new BoundLabelStatement(breakLabel);

            var result = new BoundBlockStatement(
                continueStatement,
                gotoFalseStatement,
                node.Body,
                gotoContinue,
                breakStatement);

            return(RewriteStatement(result));
        }
Esempio n. 9
0
        protected override BoundStatement RewriteForStatement(BoundForStatement node)
        {
            /*
             *  {
             *      let upperBound = <UpperBound>
             *      <variable> = <lowerBound>
             *      while <variable> < <UpperBound>
             *      {
             *          <statement>
             *          <variable> = <variable> + 1
             *      }
             *  }
             */

            var upperBoundSymbol      = new VariableSymbol("upperBound", true, node.UpperBound.Type, true);
            var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound);
            var upperBoundExpression  = new BoundVariableExpression(upperBoundSymbol);
            var variableDeclaration   = new BoundVariableDeclaration(node.Variable, node.LowerBound); // LowerBound shouldn't be rewriten?
            var variableExpression    = new BoundVariableExpression(node.Variable);
            var conditionOperator     = BoundBinaryOperator.Bind(SyntaxKind.LessToken, TypeSymbol.Int, TypeSymbol.Int);
            var condition             = new BoundBinaryExpression(variableExpression, conditionOperator, upperBoundExpression); // UpperBound shouldn't be rewriten?

            var incrementOperator   = BoundBinaryOperator.Bind(SyntaxKind.PlusToken, node.Variable.Type, TypeSymbol.Int);
            var increment           = new BoundBinaryExpression(variableExpression, incrementOperator, new BoundLiteralExpression(1));
            var incrementAssignment = new BoundAssignmentExpression(node.Variable, increment);
            var incrementStatement  = new BoundExpressionStatement(incrementAssignment);

            var whileBlockStatement = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(node.Statement, incrementStatement));
            var whileStatement      = new BoundWhileStatement(condition, whileBlockStatement);

            var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(upperBoundDeclaration, variableDeclaration, whileStatement));

            return(RewriteStatement(result));
        }
Esempio n. 10
0
        protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node)
        {
            // do
            //      <body>
            // while <condition>
            //
            // ----->
            //
            // continue:
            // <body>
            // gotoTrue <condition> continue
            //

            var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel);
            var gotoTrue            = new BoundConditionalGotoStatement(node.ContinueLabel, node.Condition);
            var breakLabelStatement = new BoundLabelStatement(node.BreakLabel);

            var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                     continueLabelStatement,
                                                     node.Body,
                                                     gotoTrue,
                                                     breakLabelStatement
                                                     ));

            return(RewriteStatement(result));
        }
Esempio n. 11
0
        /// <inheritdoc/>
        protected override BoundStatement RewriteForInfiniteStatement(BoundForInfiniteStatement node)
        {
            // for
            //     <body>
            //
            // ---->
            //
            // {
            //     continue:
            //     <body>
            //     goto continue
            //     break:
            // }
            var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel);
            var gotoContinue           = new BoundGotoStatement(node.ContinueLabel);
            var breakLabelStatement    = new BoundLabelStatement(node.BreakLabel);

            var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                     continueLabelStatement,
                                                     node.Body,
                                                     gotoContinue,
                                                     breakLabelStatement));

            return(RewriteStatement(result));
        }
Esempio n. 12
0
 private void EvaluateBlockStatement(BoundBlockStatement node)
 {
     foreach (var statement in node.Statements)
     {
         EvaluateStatement(statement);
     }
 }
Esempio n. 13
0
        protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node)
        {
            // goto continue
            // body:
            // <body>
            // continue:
            // goto body if <condition>
            // break:

            var bodyLabel = CreateLabel();

            var gotoContinue = new BoundGotoStatement(node.ContinueLabel, node.IsValid);
            var gotoBody     = new BoundConditionalGotoStatement(bodyLabel, node.Condition, jumpIfFalse: false, node.IsValid);


            var continueLabelStmt = new BoundLabelStatement(node.ContinueLabel, node.IsValid);
            var bodyLabelStmt     = new BoundLabelStatement(bodyLabel, node.IsValid);
            var breakLabelStmt    = new BoundLabelStatement(node.BreakLabel, node.IsValid);


            var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                  gotoContinue,
                                                  bodyLabelStmt,
                                                  node.Body,
                                                  continueLabelStmt,
                                                  gotoBody,
                                                  breakLabelStmt
                                                  ), node.IsValid);

            return(RewriteStatement(res));
        }
Esempio n. 14
0
        protected override BoundStatement RewriteIfStatement(BoundIfStatement node)
        {
            if (node.ElseStatement == null)
            {
                var endLabel          = GenerateLabel("EndIf");
                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
            {
                var endLabel  = GenerateLabel("EndIf");
                var elseLabel = GenerateLabel("IfElse");

                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));
            }
        }
Esempio n. 15
0
        private object EvaluateStatement(BoundBlockStatement body)
        {
            var labelToIndex = new Dictionary <BoundLabel, int>();

            for (var i = 0; i < body.Statements.Length; i++)
            {
                if (body.Statements[i] is BoundLabelStatement l)
                {
                    labelToIndex.Add(l.Label, i + 1);
                }
            }

            var 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:
                    var 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;

                default:
                    throw new Exception($"Unexpected node {s.Kind}");
                }
            }

            return(_lastValue);
        }
Esempio n. 16
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));
            }
        }
Esempio n. 17
0
        protected override BoundStatement RewriteForStatement(BoundForStatement node)
        {
            /*
             *  for <var> = <lower> to <upper>
             *      <body>
             *
             *  ----->
             *  {
             *      var <var> = <lower>
             *      let upperBound = <upper>
             *      while (<var> <= <upperBound>)
             *      {
             *          <body>
             *          <var> = <var> + 1
             *      }
             *  }
             */
            // var <var> = <lower>
            var variableDeclaration = new BoundVariableDeclaration(node.Variable, node.LowerBound);

            // let upperBound = <upper>
            var upperBoundSymbol      = new VariableSymbol("upperBound", true, TypeSymbol.Int);
            var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound);

            // <var>
            var variableExpression = new BoundVariableExpression(node.Variable);

            //<var> <= <upperBound>
            var condition = new BoundBinaryExpression(
                variableExpression,
                BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualsToken, TypeSymbol.Int, TypeSymbol.Int),
                new BoundVariableExpression(upperBoundSymbol)
                );

            // <var> = <var> + 1
            var increment = new BoundExpressionStatement(
                new BoundAssignmentExpression(
                    node.Variable,
                    new BoundBinaryExpression(
                        variableExpression,
                        BoundBinaryOperator.Bind(SyntaxKind.PlusToken, TypeSymbol.Int, TypeSymbol.Int),
                        new BoundLiteralExpression(1)
                        )
                    )
                );

            var whileBlock     = new BoundBlockStatement(ImmutableArray.Create(node.Body, increment));
            var whileStatement = new BoundWhileStatement(condition, whileBlock);

            var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                     variableDeclaration,
                                                     upperBoundDeclaration,
                                                     whileStatement));

            return(RewriteStatement(result));
        }
Esempio n. 18
0
        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 variableDeclaration   = new BoundVariableDeclaration(node.Variable, node.LowerBound);
            var variableExpression    = new BoundVariableExpression(node.Variable);
            var upperBoundSymbol      = new LocalVariableSymbol("upperBound", true, TypeSymbol.Int);
            var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound);
            var condition             = new BoundBinaryExpression(
                variableExpression,
                BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualsToken, TypeSymbol.Int, TypeSymbol.Int),
                new BoundVariableExpression(upperBoundSymbol)
                );
            var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel);
            var increment = new BoundExpressionStatement(
                new BoundAssignmentExpression(
                    node.Variable,
                    new BoundBinaryExpression(
                        variableExpression,
                        BoundBinaryOperator.Bind(SyntaxKind.PlusToken, TypeSymbol.Int, TypeSymbol.Int),
                        new BoundLiteralExpression(1)
                        )
                    )
                );
            var whileBody = new BoundBlockStatement(
                ImmutableArray.Create <BoundStatement>(
                    node.Body,
                    continueLabelStatement,
                    increment
                    )
                );
            var whileStatement = new BoundWhileStatement(condition, whileBody, node.BreakLabel, GenerateLabel());
            var result         = new BoundBlockStatement(
                ImmutableArray.Create <BoundStatement>(
                    variableDeclaration,
                    upperBoundDeclaration,
                    whileStatement
                    )
                );

            return(RewriteStatement(result));
        }
Esempio n. 19
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));
            }
        }
Esempio n. 20
0
        protected override BoundStatement RewriteForStatement(BoundForStatement node)
        {
            var initializer            = new BoundExpressionStatement(node.Initializer);
            var loop                   = new BoundExpressionStatement(node.Loop);
            var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel);

            var whileBlock     = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(node.Body, continueLabelStatement, loop));
            var whileStatement = new BoundWhileStatement(node.Condition, whileBlock, node.BreakLabel, GenerateLabel());
            var result         = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(initializer, whileStatement));

            return(RewriteStatement(result));
        }
Esempio n. 21
0
 private static void WriteBoundBlockStatement(this IndentedTextWriter writer, BoundBlockStatement node)
 {
     writer.ColorWrite("{");
     writer.Indent += 4;
     foreach (var n in node.Statements)
     {
         writer.WriteLine();
         writer.WriteBoundNode(n);
     }
     writer.Indent -= 4;
     writer.WriteLine();
     writer.ColorWrite("}");
 }
Esempio n. 22
0
        protected override BoundStatement RewriteForToStatement(BoundForToStatement node)
        {
            // for <var> = <lower> to <upper> <body>
            // --- to --->
            // {
            // var <var> = <lower>
            // let upperBound = <upper>
            // while <var> <= upperBound
            //     <body>
            //     continue:
            //     <var> = <var> + 1
            // }

            var variableDeclaration
                = new BoundVariableDeclarationStatement(node.Variable, node.LowerBound);

            var upperBoundSymbol = new LocalVariableSymbol("upperBound", true, TypeSymbol.Int);
            var upperBoundDeclaration
                = new BoundVariableDeclarationStatement(upperBoundSymbol, node.UpperBound);
            var upperBoundExpression = new BoundVariableExpression(upperBoundSymbol);

            var condition = new BoundBinaryExpression(
                new BoundVariableExpression(node.Variable),
                BoundBinaryOperator.Bind(Lexing.TokenKind.LessOrEquals, TypeSymbol.Int, TypeSymbol.Int),
                upperBoundExpression);

            var increment = new BoundExpressionStatement(
                new BoundAssignmentExpression(
                    node.Variable,
                    new BoundBinaryExpression(
                        new BoundVariableExpression(node.Variable),
                        BoundBinaryOperator.Bind(Lexing.TokenKind.Plus, TypeSymbol.Int, TypeSymbol.Int),
                        new BoundLiteralExpression(1))));

            var whileBlock =
                new BoundBlockStatement(
                    node.Body,
                    increment);

            var whileStatement
                = new BoundWhileStatement(condition, whileBlock, node.BreakLabel, node.ContinueLabel);

            var result = new BoundBlockStatement(
                variableDeclaration,
                upperBoundDeclaration,
                whileStatement);

            return(RewriteStatement(result));
        }
Esempio n. 23
0
        private static BoundBlockStatement RemoveDeadCode(BoundBlockStatement node)
        {
            var controlFlow         = ControlFlowGraph.Create(node);
            var reachableStatements = new HashSet <BoundStatement>(controlFlow.Blocks.SelectMany(b => b.Statements));
            var builder             = node.Statements.ToBuilder();

            for (var i = builder.Count - 1; i >= 0; i--)
            {
                if (!reachableStatements.Contains(builder[i]))
                {
                    builder.RemoveAt(i);
                }
            }

            return(new BoundBlockStatement(node.Syntax, builder.ToImmutable()));
        }
Esempio n. 24
0
        protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node)
        {
            var continueLabelStmt = new BoundLabelStatement(node.ContinueLabel, node.IsValid);
            var breakLabelStmt    = new BoundLabelStatement(node.BreakLabel, node.IsValid);

            var gotoContinue = new BoundConditionalGotoStatement(node.ContinueLabel, node.Condition, jumpIfFalse: false, node.IsValid);

            var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                  continueLabelStmt,
                                                  node.Body,
                                                  gotoContinue,
                                                  breakLabelStmt
                                                  ), node.IsValid);

            return(RewriteStatement(res));
        }
Esempio n. 25
0
        protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node)
        {
            var bodyLabel = GenerateLabel();

            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>(
                                                     bodyLabelStatement,
                                                     node.Body,
                                                     continueLabelStatement,
                                                     gotoTrue,
                                                     breakLabelStatement
                                                     ));

            return(RewriteStatement(result));
        }
Esempio n. 26
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));
        }
Esempio n. 27
0
        private object EvaluateCallExpression(BoundCallExpression node)
        {
            if (node.Function == BuiltinFunctions.Input)
            {
                return(Console.ReadLine());
            }
            else if (node.Function == BuiltinFunctions.Print)
            {
                string message = (string)EvaluateExpression(node.Arguments[0]);
                Console.WriteLine(message);
                return(null);
            }
            else if (node.Function == BuiltinFunctions.Rnd)
            {
                int max = (int)EvaluateExpression(node.Arguments[0]);
                if (random == null)
                {
                    random = new Random();
                }

                return(random.Next(max));
            }
            else
            {
                Dictionary <VariableSymbol, object> localVars = new Dictionary <VariableSymbol, object>();

                for (int i = 0; i < node.Arguments.Length; i++)
                {
                    ParameterSymbol parameter = node.Function.Parameters[i];
                    object          value     = EvaluateExpression(node.Arguments[i]);
                    localVars.Add(parameter, value);
                }

                locals.Push(localVars);
                BoundBlockStatement statement = program.Functions[node.Function];
                object result = EvaluateStatement(statement);
                locals.Pop();

                return(result);
            }
        }
Esempio n. 28
0
        private void EmitFunctionBody(FunctionSymbol function, BoundBlockStatement body)
        {
            var method = _methods[function];

            _locals.Clear();

            var ilProcessor = method.Body.GetILProcessor();

            foreach (var statement in body.Statements)
            {
                EmitStatement(ilProcessor, statement);
            }

            // HACK: We should make sure that our bound tree has explicit returns.
            if (function.Type == TypeSymbol.Void)
            {
                ilProcessor.Emit(OpCodes.Ret);
            }

            method.Body.OptimizeMacros();
        }
Esempio n. 29
0
        protected override BoundStatement RewriteForStatement(BoundForStatement node)
        {
            var condition = node.Condition;

            var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel);
            var increment = new BoundExpressionStatement(
                node.Action
                );
            var whileBody = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                        node.Body,
                                                        continueLabelStatement,
                                                        increment)
                                                    );
            var whileStatement = new BoundWhileStatement(condition, whileBody, node.BreakLabel, GenerateLabel());
            var result         = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(
                                                             node.Variable,
                                                             whileStatement
                                                             ));

            return(RewriteStatement(result));
        }
Esempio n. 30
0
        protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node)
        {
            BoundLabel bodyLabel = GenerateLabel();
            BoundLabel endLabel  = new BoundLabel("End");

            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>(
                                                                               bodyLabelStatement,
                                                                               node.Body,
                                                                               continueLabelStatement,
                                                                               gotoTrue,
                                                                               breakLabelStatement,
                                                                               endLabelStatement
                                                                               ));

            return(RewriteStatement(result));
        }