public void DeferRendering(StructureNode predecessor, StructureNode node, AbsynStatementEmitter emitter) { foreach (NodeEmitter ne in nodesToRender) { if (ne.Node == node) return; } nodesToRender.Enqueue(new NodeEmitter(predecessor, node, emitter)); }
public void GenerateCode(AbsynCodeGenerator codeGen, StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { if (Follow != null) codeGen.PushFollow(Follow); GenerateCodeInner(codeGen, node, emitter); if (Follow != null) { codeGen.PopFollow(); codeGen.GenerateCode(Follow, latchNode, emitter); } }
public override void GenerateCode(AbsynCodeGenerator codeGen, StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { codeGen.EmitLinearBlockStatements(node, emitter); if (node == latchNode) return; var exp = codeGen.BranchCondition(node); var ifStm = EmitIfCondition(exp, this, emitter); var succ = FirstBranch(node); var emitThen = new AbsynStatementEmitter(ifStm.Then); if (node.UnstructType == UnstructuredType.JumpInOutLoop) { codeGen.DeferRendering(node, succ, emitThen); codeGen.GenerateCode(SecondBranch(node), latchNode, emitter); } else { if (Follow == null) throw new NotSupportedException("Null condfollow"); codeGen.PushFollow(Follow); if (node.Conditional is IfThenElse) { codeGen.IncompleteNodes.Add(node); } if (codeGen.IsVisited(succ) || (node.Loop != null && succ == node.Loop.Follow)) codeGen.EmitGotoAndForceLabel(node, succ, emitThen); else codeGen.GenerateCode(succ, latchNode, emitThen); if (node.Conditional is IfThenElse) { codeGen.IncompleteNodes.Remove(node); succ = node.Then; AbsynStatementEmitter emitElse = new AbsynStatementEmitter(ifStm.Else); if (codeGen.IsVisited(succ)) codeGen.EmitGotoAndForceLabel(node, succ, emitElse); else codeGen.GenerateCode(succ, latchNode, emitElse); if (HasSingleIfThenElseStatement(ifStm.Then)) { ifStm.InvertCondition(); } } codeGen.PopFollow(); codeGen.GenerateCode(Follow, latchNode, emitter); } }
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); }
protected abstract void GenerateCodeInner(AbsynCodeGenerator codeGen, StructureNode node, AbsynStatementEmitter emitter);
protected override void GenerateCodeInner(AbsynCodeGenerator codeGen, StructureNode node, AbsynStatementEmitter emitter) { List<AbsynStatement> loopBody = new List<AbsynStatement>(); AbsynStatementEmitter bodyEmitter = new AbsynStatementEmitter(loopBody); if (node.Conditional != null) { node.Conditional.GenerateCode(codeGen, node, Latch, bodyEmitter); } else { codeGen.EmitLinearBlockStatements(node, bodyEmitter); if (node.OutEdges.Count != 1) throw new NotSupportedException(string.Format("Expected top of PostTestedLoop {0} to have only 1 out edge, but found {1} out edges.", node.Name, node.OutEdges.Count)); codeGen.GenerateCode(node.OutEdges[0], Latch, bodyEmitter); } emitter.EmitForever(node, loopBody); }
protected override void GenerateCodeInner(AbsynCodeGenerator codeGen, StructureNode node, AbsynStatementEmitter emitter) { codeGen.EmitLinearBlockStatements(node, emitter); var loopBody = new List<AbsynStatement>(); var bodyNode = (node.Else == node.Loop.Follow) ? node.Then : node.Else; var bodyEmitter = new AbsynStatementEmitter(loopBody); codeGen.GenerateCode(bodyNode, node.Loop.Latch, bodyEmitter); bodyEmitter.StripDeclarations = true; codeGen.EmitLinearBlockStatements(node, bodyEmitter); emitter.EmitWhile(node, codeGen.BranchCondition(node), loopBody); }
public void Setup() { m = new ProcedureBuilder(); stms = new List<AbsynStatement>(); emitter = new AbsynStatementEmitter(stms); }
public void GenerateCode( StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { if (followStack.Contains(node) && followStack.Peek() == node) return; if (IsVisited(node)) return; visited.Add(node); if (NeedsLabel(node)) GenerateLabel(node,emitter); if (node.IsLoopHeader()) { node.Loop.GenerateCode(this, node, latchNode, emitter); } else if (node.Conditional != null) { node.Conditional.GenerateCode(this, node, latchNode, emitter); } else { EmitLinearBlockStatements(node, emitter); if (EndsWithReturnInstruction(node)) { emitter.EmitStatement(node.Instructions.Last); return; } if (node.IsLatchNode()) return; if (node.OutEdges.Count == 1) { StructureNode succ = node.OutEdges[0]; if (ShouldJumpFromSequentialNode(node, succ)) EmitGotoAndForceLabel(node, succ, emitter); else GenerateCode(succ, latchNode, emitter); } } }
public NodeEmitter(StructureNode pred, StructureNode node, AbsynStatementEmitter emitter) { this.Predecessor = pred; this.Node = node; this.Emitter = emitter; }
public void EmitLinearBlockStatements(StructureNode node, AbsynStatementEmitter emitter) { foreach (Statement stm in node.Instructions) { if (stm.Instruction.IsControlFlow) return; emitter.EmitStatement(stm); } }
private void GenerateLabel(StructureNode node, AbsynStatementEmitter emitter) { emitter.EmitLabel(node); }
public abstract void GenerateCode(AbsynCodeGenerator codeGen, StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter);
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); }
private AbsynIf EmitIfCondition(Expression exp, Conditional cond, AbsynStatementEmitter emitter) { if (cond is IfElse || cond is IfThenElse) { exp = exp.Invert(); } AbsynIf ifStm = new AbsynIf(); ifStm.Condition = exp; emitter.EmitStatement(ifStm); return ifStm; }