protected override BoundStatement RewriteIfStatement(BoundIfStatement statement) { /* if(<condition>) <true> else <false> * * condiditonal branch !<condition> false * <true> * branch end * * #false * <false> * #end */ var falseLabel = CreateNextLabel(); var endLabel = CreateNextLabel(); var endBranch = new BoundBranchStatement(endLabel); var statements = ImmutableArray.CreateBuilder <BoundStatement>(); if (statement.FalseBranch != null) { var condBranch = new BoundConditionalBranchStatement(falseLabel, statement.Condition, false); statements.AddRange(condBranch, statement.TrueBranch, endBranch, new BoundLabel(falseLabel), statement.FalseBranch); } else { var condBranch = new BoundConditionalBranchStatement(endLabel, statement.Condition, false); statements.AddRange(condBranch, statement.TrueBranch); } statements.Add(new BoundLabel(endLabel)); return(RewriteStatement(new BoundBlock(statements.ToImmutable()))); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement statement) { /* while(<condition>) <body> * * branch conditionCheck * #start * <body> * #conditionCheck * conditional branch <condition> start */ var startLabel = CreateNextLabel(); var conditionCheckLabel = CreateNextLabel(); var firstBranch = new BoundBranchStatement(conditionCheckLabel); var condBranch = new BoundConditionalBranchStatement(startLabel, statement.Condition, true); var statements = ImmutableArray.CreateBuilder <BoundStatement>(); statements.AddRange(new BoundStatement[] { firstBranch, new BoundLabel(startLabel), statement.Body }); if (statement.AddContinue) { statements.Add(new BoundLabel(statement.ContinueLabel)); } statements.AddRange(new BoundStatement[] { new BoundLabel(conditionCheckLabel), condBranch, new BoundLabel(statement.BreakLabel) }); var rewrite = RewriteStatement(new BoundBlock(statements.ToImmutable())); return(rewrite); }
protected virtual BoundStatement RewriteBranchStatement(BoundBranchStatement statement) { return(statement); }
private void OutputBranch(BoundBranchStatement node, string prefix) { builder.AddFragment(new OutputFragment(prefix, DefaultColour)); builder.AddFragment(new OutputFragment("goto ", BranchColour)); builder.AddFragment(new OutputFragment(node.Label.Name, LabelColour)); }