public void EmitGotoAndForceLabel(StructureNode node, StructureNode succ, AbsynStatementEmitter emitter) { if (node == null) throw new InvalidOperationException("A goto must have a starting point."); if (node.Loop != null) { if (node.Loop.Follow == succ) { emitter.EmitBreak(); return; } if (node.Loop.Header == succ) { emitter.EmitContinue(); return; } } succ.ForceLabel = true; emitter.EmitGoto(succ); }
public override void GenerateCode(AbsynCodeGenerator codeGen, StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { codeGen.EmitLinearBlockStatements(node, emitter); Expression exp = ((SwitchInstruction) node.Instructions.Last.Instruction).Expression; AbsynSwitch switchStm = emitter.EmitSwitch(node, exp, new List<AbsynStatement>()); AbsynStatementEmitter emitSwitchBranches = new AbsynStatementEmitter(switchStm.Statements); if (Follow == null) throw new NotSupportedException(string.Format("Null follow node for case statement at {0} is not supported.", node.Name)); codeGen.PushFollow(Follow); for (int i = 0; i < node.OutEdges.Count; i++) { emitSwitchBranches.EmitCaseLabel(node, i); StructureNode succ = node.OutEdges[i]; if (codeGen.IsVisited(succ)) { codeGen.EmitGotoAndForceLabel(node, succ, emitSwitchBranches); } else { codeGen.GenerateCode(succ, latchNode, emitSwitchBranches); emitSwitchBranches.EmitBreak(); } } codeGen.PopFollow(); codeGen.GenerateCode(Follow, latchNode, emitter); }