public override void VisitFor(ForStatement forStatement) { Visit(forStatement.From); Program.Add(new Assignment(forStatement.ForVariable.Name, ExpressionStack.Pop())); var forBegin = NewLabel; var forEnd = NewLabel; var forVariable = new Identifier(forStatement.ForVariable.Name); Visit(forStatement.To); var forTo = ExpressionStack.Pop(); var check = new ConditionalGoto( forEnd, new BinaryOperation(forVariable, Operation.Greater, forTo)) { Label = forBegin }; Program.Add(check); Visit(forStatement.Body); Program.Add(Assignment.Increment(forVariable.Name)); Program.Add(new Goto(forBegin)); Program.Add(new NoOperation(forEnd)); }
protected bool Equals(ConditionalGoto other) { return(base.Equals(other) && Equals(Condition, other.Condition)); }
public List <ThreeAddressCommand> transformToThreeAddressCode() { var res = new List <ThreeAddressCommand>(); var done = new HashSet <BasicBlock>(); var stack = new Stack <BasicBlock>(); stack.Push(getBlockById(GetMinBlockId())); BasicBlock cur = null; while (done.Count < this.GetCount()) { cur = stack.Pop(); done.Add(cur); foreach (var c in cur.Commands) { res.Add(c); } switch (cur.OutputBlocks.Count) { case 0: continue; case 1: BasicBlock outBlock = getBlockById(cur.OutputBlocks[0]); if (!done.Contains(outBlock) && !stack.Contains(outBlock)) { stack.Push(outBlock); } break; case 2: int lastStatementIndex = cur.Commands.Count - 1; ConditionalGoto lastStatement = (ConditionalGoto)cur.Commands[lastStatementIndex]; BasicBlock outFirst = getBlockById(cur.OutputBlocks[0]); BasicBlock outSecond = getBlockById(cur.OutputBlocks[1]); string labelFirst = outFirst.Commands[0].Label; string labelSecond = outSecond.Commands[0].Label; string gotoLabel = lastStatement.GotoLabel; if (gotoLabel == labelFirst) { BasicBlock t = outFirst; outFirst = outSecond; outSecond = t; } int firstLastIndex = outFirst.Commands.Count - 1; ThreeAddressCommand secondLast = outFirst.Commands[firstLastIndex]; if ((secondLast is Goto) && !(secondLast is ConditionalGoto)) { BasicBlock afterIfStatement = getBlockById(outFirst.OutputBlocks[0]); if (!stack.Contains(afterIfStatement) && !done.Contains(afterIfStatement)) { stack.Push(afterIfStatement); } } if (!done.Contains(outSecond) && !stack.Contains(outSecond)) { stack.Push(outSecond); } if (!done.Contains(outFirst) && !stack.Contains(outFirst)) { stack.Push(outFirst); } break; default: throw new Exception("There cannot be more than two output blocks!"); } } return(res); }