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("}"); }
protected override BoundExpression RewriteBlockExpression(BoundBlockExpression node) { if (node.Statements.IsEmpty) { } return(base.RewriteBlockExpression(node)); }
private static void EmitTree(Symbol method, BoundBlockExpression block, TextWriter writer) { method.WriteTo(writer); writer.WritePunctuation(" = "); writer.WriteLine(); block.WriteTo(writer); }
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)); }
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)); }
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)); }
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)); }
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()); }
public virtual void VisitBlockExpression(BoundBlockExpression node) => this.DefaultVisit(node);
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)); }
private bool ContainsBlock(BoundBlockExpression block) => block.Statements.Any(ContainsBlock) || ContainsBlock(block.Expression);
public static BoundBlockExpression Lower(Symbol method, BoundBlockExpression blockExpression) => new InlineTemporaries(method).Rewrite(blockExpression);