Beispiel #1
0
    public override void VisitBlockExpression(BoundBlockExpression node)
    {
        if (node.Statements.Length == 0)
        {
            _writer.WritePunctuation("{ ");
            node.Expression.Accept(this);
            _writer.WritePunctuation(" }");
            return;
        }

        _writer.WritePunctuation("{");
        _writer.WriteLine();
        _writer.Indent++;

        foreach (var statement in node.Statements)
        {
            statement.Accept(this);
        }

        node.Expression.Accept(this);
        _writer.WriteLine();

        _writer.Indent--;
        _writer.WritePunctuation("}");
    }
Beispiel #2
0
 protected override BoundExpression RewriteBlockExpression(BoundBlockExpression node)
 {
     if (node.Statements.IsEmpty)
     {
     }
     return(base.RewriteBlockExpression(node));
 }
Beispiel #3
0
 private static void EmitTree(Symbol method, BoundBlockExpression block, TextWriter writer)
 {
     method.WriteTo(writer);
     writer.WritePunctuation(" = ");
     writer.WriteLine();
     block.WriteTo(writer);
 }
Beispiel #4
0
    protected override BoundExpression RewriteBlockExpression(BoundBlockExpression node)
    {
        if (node.Statements.Length == 0)
        {
            return(RewriteExpression(node.Expression));
        }

        return(base.RewriteBlockExpression(node));
    }
    protected BoundBlockExpression Rewrite(BoundBlockExpression block)
    {
        foreach (var statement in block.Statements)
        {
            RewriteStatement(statement);
        }

        RewriteStatement(new BoundExpressionStatement(block.Syntax, block.Expression));

        return(GetBlock(block.Syntax));
    }
Beispiel #6
0
    protected override BoundExpression RewriteIfExpression(BoundIfExpression node)
    {
        /*
         * if (<condition>)
         *     <thenBody>
         * else
         *     <elseBody>
         *
         *
         * to
         *
         * gotoIfFalse <condition> <elseLabel>
         *    <thenBody>
         *    goto <endLabel>
         * <elseLabel>
         *     <elseBody>
         * <endLabel>
         *
         */

        var token     = GenerateLabelToken();
        var elseLabel = GenerateLabel("IfElse", token);
        var endLabel  = GenerateLabel("IfEnd", token);
        var variable  = GenerateVariable(node.Type);

        var condition = RewriteExpression(node.Condition);

        if (condition is BoundLiteralExpression literal)
        {
            return(RewriteExpression((bool)literal.Value ? node.Then : node.Else));
        }

        var then  = RewriteExpression(node.Then);
        var @else = RewriteExpression(node.Else);
        var variableExpression = new BoundVariableExpression(node.Syntax, variable);
        var block = new BoundBlockExpression(
            node.Syntax,
            ImmutableArray.Create <BoundStatement>(
                new BoundVariableDeclarationStatement(node.Syntax, variable, null),
                new BoundConditionalGotoStatement(node.Syntax, elseLabel, condition),
                new BoundAssignmentStatement(node.Syntax, variableExpression, then),
                new BoundGotoStatement(node.Syntax, endLabel),
                new BoundLabelStatement(node.Syntax, elseLabel),
                new BoundAssignmentStatement(node.Syntax, variableExpression, @else),
                new BoundLabelStatement(node.Syntax, endLabel)
                ),
            variableExpression
            );

        return(RewriteExpression(block));
    }
Beispiel #7
0
    public static BoundBlockExpression RemoveDeadCode(BoundBlockExpression block)
    {
        var controlFlow         = ControlFlowGraph.Create(block);
        var reachableStatements = new HashSet <BoundStatement>(
            controlFlow.Blocks.SelectMany(basicBlock => basicBlock.Statements)
            );

        var builder = block.Statements.ToBuilder();

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

        return(new BoundBlockExpression(block.Syntax, builder.ToImmutable(), block.Expression));
    }
Beispiel #8
0
    protected override BoundExpression RewriteBlockExpression(BoundBlockExpression node)
    {
        if (node.Statements.Length == 0)
        {
            return(RewriteExpression(node.Expression));
        }

        foreach (var boundStatement in node.Statements)
        {
            // has side effect and will be added to the list of statements
            RewriteStatement(boundStatement);
        }

        var rewritten = this.RewriteExpression(node.Expression);

        if (rewritten.Kind == BoundNodeKind.LiteralExpression)
        {
            return(rewritten);
        }

        // node.Expression had a nested block so assign it to a temp and return the variable
        return(CreateTemporary(rewritten));
    }
Beispiel #9
0
        public List <BasicBlock> Build(BoundBlockExpression block)
        {
            foreach (var statement in block.Statements)
            {
                switch (statement.Kind)
                {
                case BoundNodeKind.ConditionalGotoStatement:
                case BoundNodeKind.GotoStatement:
                    _statements.Add(statement);
                    StartBlock();
                    break;

                case BoundNodeKind.LabelStatement:
                    StartBlock();
                    _statements.Add(statement);
                    break;

                case BoundNodeKind.VariableDeclarationStatement:
                case BoundNodeKind.ExpressionStatement:
                case BoundNodeKind.AssignmentStatement:
                case BoundNodeKind.NopStatement:
                    _statements.Add(statement);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(
                              nameof(statement),
                              statement.Kind.ToString()
                              );
                }
            }

            _statements.Add(new BoundExpressionStatement(block.Syntax, block.Expression));

            EndBlock();
            return(_blocks.ToList());
        }
Beispiel #10
0
 public virtual void VisitBlockExpression(BoundBlockExpression node) =>
 this.DefaultVisit(node);
Beispiel #11
0
    protected override BoundExpression RewriteForExpression(BoundForExpression node)
    {
        /*
         * convert from for to while
         *
         * for (x <- l to u) expr
         *
         * var x = l
         * while(x < u) {
         *     expr
         *     continue:
         *     x = x + 1
         * }
         */

        var lowerBound = RewriteExpression(node.LowerBound);
        var upperBound = RewriteExpression(node.UpperBound);
        var body       = RewriteExpression(node.Body);

        var declareX = new BoundVariableDeclarationStatement(
            node.Syntax,
            node.Variable,
            lowerBound
            );

        var variableExpression = ValueExpression(node.Syntax, node.Variable);
        var condition          = new BoundBinaryExpression(
            node.Syntax,
            variableExpression,
            BoundBinaryOperator.BindOrThrow(SyntaxKind.LessThanToken, Type.Int, Type.Int),
            upperBound
            );
        var continueLabelStatement = new BoundLabelStatement(node.Syntax, node.ContinueLabel);
        var incrementX             = new BoundExpressionStatement(
            node.Syntax,
            new BoundAssignmentExpression(
                node.Syntax,
                variableExpression,
                new BoundBinaryExpression(
                    node.Syntax,
                    variableExpression,
                    BoundBinaryOperator.BindOrThrow(SyntaxKind.PlusToken, Type.Int, Type.Int),
                    new BoundLiteralExpression(node.Syntax, 1)
                    )
                )
            );
        var whileBody = new BoundBlockExpression(
            node.Syntax,
            ImmutableArray.Create <BoundStatement>(
                new BoundExpressionStatement(body.Syntax, body),
                continueLabelStatement,
                incrementX
                ),
            new BoundUnitExpression(node.Syntax)
            );

        var newBlock = new BoundBlockExpression(
            node.Syntax,
            ImmutableArray.Create <BoundStatement>(declareX),
            new BoundWhileExpression(
                node.Syntax,
                condition,
                whileBody,
                node.BreakLabel,
                new BoundLabel("continue")
                )
            );

        return(RewriteExpression(newBlock));
    }
Beispiel #12
0
 private bool ContainsBlock(BoundBlockExpression block) =>
 block.Statements.Any(ContainsBlock) || ContainsBlock(block.Expression);
Beispiel #13
0
 public static BoundBlockExpression Lower(Symbol method, BoundBlockExpression blockExpression) =>
 new InlineTemporaries(method).Rewrite(blockExpression);