Пример #1
0
 private static void WriteConditionalGotoStatement(BoundConditionalGotoStatement node, IndentedTextWriter writer)
 {
     writer.WriteKeyword("goto");
     writer.WriteWhiteSpace();
     writer.WriteIdentifier(node.Label.Name);
     writer.WriteWhiteSpace();
     writer.WriteKeyword(node.JumpIfTrue ? "if" : "unless");
     writer.WriteWhiteSpace();
     node.Condition.WriteTo(writer);
     writer.WriteLine();
 }
Пример #2
0
            public ControlFlowGraph Build(List <BasicBlock> blocks)
            {
                if (!blocks.Any())
                {
                    Connect(start, end);
                }
                else
                {
                    Connect(start, blocks.First());
                }

                foreach (BasicBlock block in blocks)
                {
                    foreach (var statement in block.Statements)
                    {
                        blockFromStatement.Add(statement, block);
                        if (statement is BoundLabelStatement labelStatement)
                        {
                            blockFromLabel.Add(labelStatement.Label, block);
                        }
                    }
                }

                for (int i = 0; i < blocks.Count; i++)
                {
                    BasicBlock current = blocks[i];
                    var        next    = i == blocks.Count - 1 ? end : blocks[i + 1];

                    foreach (var statement in current.Statements)
                    {
                        bool isLastStatementInBlock = statement == current.Statements.Last();
                        switch (statement.Kind)
                        {
                        case BoundNodeKind.GotoStatement:
                            BoundGotoStatement gs      = (BoundGotoStatement)statement;
                            BasicBlock         toBlock = blockFromLabel[gs.Label];
                            Connect(current, toBlock);
                            break;

                        case BoundNodeKind.ConditionalGotoStatement:
                            BoundConditionalGotoStatement cgs = (BoundConditionalGotoStatement)statement;
                            BasicBlock      themBlock         = blockFromLabel[cgs.Label];
                            BasicBlock      elseBlock         = next;
                            BoundExpression negatedCondition  = Negate(cgs.Condition);
                            BoundExpression thenCondition     = cgs.JumpIfTrue ? cgs.Condition: negatedCondition;
                            BoundExpression elseCondition     = cgs.JumpIfTrue ? negatedCondition: cgs.Condition;
                            Connect(current, themBlock, thenCondition);
                            Connect(current, elseBlock, elseCondition);
                            break;

                        case BoundNodeKind.ReturnStatement:
                            Connect(current, end);
                            break;

                        case BoundNodeKind.LabelStatement:
                        case BoundNodeKind.VariableDeclaration:
                        case BoundNodeKind.ExpressionStatement:
                            if (isLastStatementInBlock)
                            {
                                Connect(current, next);
                            }
                            break;

                        default:
                            throw new Exception($"Unexpected statemend: '{statement.Kind}'.");
                        }
                    }
                }

ScanAgain:
                foreach (BasicBlock block in blocks)
                {
                    if (!block.Incoming.Any())
                    {
                        RemoveBlock(blocks, block);
                        goto ScanAgain;
                    }
                }

                blocks.Insert(0, start);
                blocks.Add(end);

                return(new ControlFlowGraph(start, end, blocks, branches));
            }