浏览代码

PseudoCodeProcessor hinzugefügt

Kolja Strohm 6 年之前
父节点
当前提交
fc211997e9

+ 28 - 69
src/animation/AnimatedAlgorithm.java

@@ -2,15 +2,12 @@ package animation;
 
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
-import java.util.Stack;
 
 import javax.swing.JFrame;
 import javax.swing.JTree;
 import javax.swing.SwingUtilities;
 
-import animation.Memory.MemoryType;
-import animation.PseudoCodeNode.CodeStatus;
-import animation.StackFrame.FrameType;
+import animation.PseudoCodeProcessor.CodeStatus;
 import graph.LayeredGraphNode;
 
 public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage {
@@ -19,8 +16,7 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
     protected LayeredGraphNode graph;
     private JFrame view;
     protected PseudoCodeNode root;
-    protected Stack<PseudoCodeNode> activeFunction;
-    protected Memory mem;
+    protected PseudoCodeProcessor processor;
 
     public AnimatedAlgorithm( AnimationController controller, LayeredGraphNode graph, JFrame view )
     {
@@ -28,36 +24,6 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
         this.graph = graph;
         this.view = view;
         root = null;
-        mem = new Memory();
-        mem.declare( "graph", graph, MemoryType.GLOBAL );
-        mem.addFrame( new StackFrame( FrameType.FUNCTION ) );
-        activeFunction = new Stack<PseudoCodeNode>();
-    }
-    
-    public Memory getMemory()
-    {
-        return mem;
-    }
-    
-    public void addActiveFunction( PseudoCodeNode n )
-    {
-    	if( !activeFunction.empty() )
-    		activeFunction.peek().writeToStack( mem );
-    	activeFunction.push( n );
-    }
-    
-    public PseudoCodeNode getActiveFunction()
-    {
-    	if( activeFunction.empty() )
-    		return null;
-    	return activeFunction.peek();
-    }
-    
-    public boolean isActiveFunction( PseudoCodeNode n )
-    {
-    	if( activeFunction.empty() )
-    		return false;
-    	return activeFunction.peek() == n;
     }
 
     private void update()
@@ -80,31 +46,32 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
         {
         	CodeStatus status = null;
             try {
-            	while( activeFunction.size() == 0 )
-            		Thread.sleep( 100 );
-            	PseudoCodeNode current = activeFunction.peek();
-                switch( ac.getNextAction() )
+                if( processor != null )
                 {
-                case FORWARD:
-                	status = current.forwardStep( mem );
-                    break;
-                case FORWARD_OUT:
-                    status = current.forwardStepOut( mem );
-                    break;
-                case FORWARD_OVER:
-                    status = current.forwardStepOver( mem );
-                    break;
-                case BACKWARD:
-                    status = current.backwardStep( mem );
-                    break;
-                case BACKWARD_OUT:
-                    status = current.backwardStepOut( mem );
-                    break;
-                case BACKWARD_OVER:
-                    status = current.backwardStepOver( mem );
-                    break;
+                    switch( ac.getNextAction() )
+                    {
+                    case FORWARD:
+                    	status = processor.forwardStep();
+                        break;
+                    case FORWARD_OUT:
+                        status = processor.forwardStepOut();
+                        break;
+                    case FORWARD_OVER:
+                        status = processor.forwardStepOver();
+                        break;
+                    case BACKWARD:
+                        status = processor.backwardStep();
+                        break;
+                    case BACKWARD_OUT:
+                        status = processor.backwardStepOut();
+                        break;
+                    case BACKWARD_OVER:
+                        status = processor.backwardStepOver();
+                        break;
+                    }
                 }
-                System.out.println( "Stack Frames: " + mem.getSize() );
+                else
+                    status = CodeStatus.FINISHED;
             } catch (InterruptedException e) {
                 e.printStackTrace();
                 return;
@@ -112,16 +79,8 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
             update();
             if( status == CodeStatus.FINISHED )
             {
-            	if( activeFunction.size() > 1 )
-            	{
-            		activeFunction.pop();
-            		activeFunction.peek().loadFromStack( mem );
-            	}
-            	else
-            	{
-            		ac.setContinuous( false );
-            		ac.setNextAction( null );
-            	}
+        		ac.setContinuous( false );
+        		ac.setNextAction( null );
             }
         }
     }

+ 9 - 383
src/animation/PseudoCodeNode.java

@@ -6,8 +6,6 @@ import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.MutableTreeNode;
 import javax.swing.tree.TreePath;
 
-import animation.Memory.MemoryType;
-
 /**
  * represents a line of pseudocode
  * @author kolja
@@ -21,13 +19,6 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
         STOP,
         CONTINUE
     }
-
-    public static enum CodeStatus
-    {
-        UNFINISHED,
-        BREAKPOINT,
-        FINISHED
-    }
     
     private static final long serialVersionUID = 1L;
 
@@ -39,10 +30,6 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
     private CodeLine code;
     private boolean selected;
     private boolean breakPoint;
-    private boolean function;
-
-    private StackFrame childFrame; // the stackframe added from this node
-    private int currentCodeLine; // next forward code line
     
     public PseudoCodeNode( String description, JTree tree, CodeLine line, AnimatedAlgorithm alg )
     {
@@ -55,10 +42,12 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
         selected = false;
         this.tree = tree;
         breakPoint = false;
-        currentCodeLine = -1;
         code = line;
-        function = false;
-        childFrame = null;
+    }
+    
+    public int getId()
+    {
+        return nodeId;
     }
     
     public void setController( AnimationController c )
@@ -73,32 +62,6 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
         controller = c;
     }
     
-    public void writeToStack( Memory m )
-    {
-    	m.declare( "_pos" + nodeId, currentCodeLine, MemoryType.LOCAL );
-    	m.declare( "_func" + nodeId, function, MemoryType.LOCAL );
-    	m.declare( "_stack" + nodeId, childFrame, MemoryType.LOCAL );
-    	currentCodeLine = -1;
-    	function = false;
-    	childFrame = null;
-    	setSelected( false );
-    	if( children == null )
-    		return;
-    	for( Object c : children )
-    		((PseudoCodeNode)c).writeToStack( m );
-    }
-    
-    public void loadFromStack( Memory m )
-    {
-    	currentCodeLine = m.read( "_pos" + nodeId, MemoryType.LOCAL );
-    	function = m.read( "_func" + nodeId, MemoryType.LOCAL );
-    	childFrame = m.read( "_stack" + nodeId, MemoryType.LOCAL );
-    	if( children == null )
-    		return;
-    	for( Object c : children )
-    		((PseudoCodeNode)c).loadFromStack( m );
-    }
-    
     @Override
     public void add( MutableTreeNode node )
     {
@@ -208,350 +171,13 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
         return breakPoint;
     }
     
-    private PseudoCodeNode getForwardNode()
-    {
-        if( currentCodeLine == -1 )
-            return this;
-        if( children != null && children.size() > currentCodeLine )
-            return ((PseudoCodeNode)children.get( currentCodeLine )).getForwardNode();
-        return this;
-    }
-    
-    private PseudoCodeNode getBackwardNode()
-    {
-        if( currentCodeLine - 1 <= -1 )
-            return this;
-        if( children != null && children.size() >= currentCodeLine - 1 )
-            return ((PseudoCodeNode)children.get( currentCodeLine - 1 )).getBackwardNode();
-        return this;
-    }
-    
-    private CodeStatus stepInto( Memory m )
-    {
-        currentCodeLine = 0;
-        if( children == null || children.size() == 0 )
-        {
-            setSelected( false );
-            return CodeStatus.FINISHED;
-        }
-        else
-        {
-            setSelected( false );
-            return selectChild( 0, m );
-        }
-    }
-    
-    /**
-     * Perform one atomic step of the algorithm. Stops at the end of the program.
-     * @return whether the whole stage is finished (afterwards).
-     * For example if all steps are finished, then {@code FINISHED} is returned.
-     */
-    public CodeStatus forwardStep( Memory m )
-    {
-        m.setCurrent( childFrame );
-        if( currentCodeLine == -1 )
-        {
-			if( !m.isDefined( "node_" + nodeId + "_call", MemoryType.LOCAL ) )
-			{
-				StackFrame tmp = null;
-				if( function )
-				{
-					tmp = m.removeFrame();
-					m.addFrame( tmp ); // a little abuse of the stack to get direct access of the current frame before it could be destroyed by the user defined function
-				}
-				ControlFlow cf = code.runForward( m );
-	            switch( cf.getStatus() )
-	            {
-	            case ControlFlow.STEP_INTO:
-	                childFrame = m.removeFrame();
-	                m.addFrame( childFrame );
-	                if( children != null )
-	                {
-    	                for( Object c : children )
-    	                    ((PseudoCodeNode)c).writeToStack( m );
-	                }
-	            	function = true;
-	                switch( stepInto( m ) )
-	                {
-					case BREAKPOINT:
-					    hiddenActionWithoutSideEffects( m );
-						return CodeStatus.BREAKPOINT;
-					case FINISHED:
-						currentCodeLine = -1;
-	                    switch( setSelected( true ) )
-	                    {
-						case SKIP:
-	                        hiddenActionWithoutSideEffects( m );
-							return forwardStepOverIntern( m );
-						case STOP:
-	                        hiddenActionWithoutSideEffects( m );
-							return CodeStatus.BREAKPOINT;
-						default:
-							break;
-	                    }
-					case UNFINISHED:
-                        hiddenActionWithoutSideEffects( m );
-						return CodeStatus.UNFINISHED;
-	                }
-	            case ControlFlow.STEP_OVER:
-	            	if( function )
-	            	{
-	            		m.addFrame( tmp ); // add old stack frame
-	                    if( children != null )
-	                    {
-	                        for( Object c : children )
-	                            ((PseudoCodeNode)c).loadFromStack( m );
-	                    }
-	                	m.removeFrame(); // remove the stack frame
-	                	setSelected( false );
-	            	}
-                    hiddenActionWithoutSideEffects( m );
-	                return CodeStatus.FINISHED;
-	            case ControlFlow.CALL:
-	    			alg.addActiveFunction( cf.getFunction() );
-	    			m.declare( "node_" + nodeId + "_call", cf.getFunction(), MemoryType.LOCAL );
-	    			setSelected( false );
-	    			m.declare( "callback", this, MemoryType.GLOBAL );
-	    			switch( cf.getFunction().setSelected( true ) )
-	    			{
-					case CONTINUE:
-						break;
-					case SKIP:
-						switch( cf.getFunction().forwardStepOverIntern( m ) )
-	        			{
-						case BREAKPOINT:
-	                        hiddenActionWithoutSideEffects( m );
-							return CodeStatus.BREAKPOINT;
-						case FINISHED:
-							setSelected( true );
-						case UNFINISHED:
-	                        hiddenActionWithoutSideEffects( m );
-							return CodeStatus.UNFINISHED;
-	        			}
-						break;
-					case STOP:
-                        hiddenActionWithoutSideEffects( m );
-						return CodeStatus.BREAKPOINT;
-	    			}
-                    hiddenActionWithoutSideEffects( m );
-	    			return CodeStatus.UNFINISHED;
-	            }
-			}
-			else
-			{
-				m.undeclare( "node_" + nodeId + "_call", MemoryType.LOCAL );
-                hiddenActionWithoutSideEffects( m );
-				return CodeStatus.FINISHED;
-			}
-        }
-        else
-        {
-            if( children == null || children.size() <= currentCodeLine )
-            {
-            	throw new IllegalStateException( "Some wired stuff is going on" );
-            }
-            switch( ( (PseudoCodeNode)children.get( currentCodeLine ) ).forwardStep( m ) )
-            {
-            case BREAKPOINT:
-                hiddenActionWithoutSideEffects( m );
-                return CodeStatus.BREAKPOINT;
-            case FINISHED:
-                hiddenActionWithoutSideEffects( m );
-                return childNodeFinished( m );
-            case UNFINISHED:
-                hiddenActionWithoutSideEffects( m );
-                return CodeStatus.UNFINISHED;
-            }
-        }
-        hiddenActionWithoutSideEffects( m );
-        return CodeStatus.UNFINISHED;
-    }
-    
-    private CodeStatus childNodeFinished( Memory m )
-    {
-        ( (PseudoCodeNode)children.get( currentCodeLine ) ).setSelected( false );
-    	currentCodeLine++;
-        if( children.size() <= currentCodeLine )
-        {
-            currentCodeLine = -1;
-            switch( setSelected( true ) )
-            {
-			case SKIP:
-				return forwardStepOverIntern( m );
-			case STOP:
-				return CodeStatus.BREAKPOINT;
-			default:
-				break;
-            }
-        }
-        else
-        {
-            CodeStatus status = selectChild( currentCodeLine, m );
-            if( status == CodeStatus.FINISHED )
-            {
-                currentCodeLine = -1;
-                status = CodeStatus.UNFINISHED;
-                switch( setSelected( true ) )
-                {
-				case SKIP:
-					return forwardStepOverIntern( m );
-				case STOP:
-					return CodeStatus.BREAKPOINT;
-				default:
-					break;
-                }
-            }
-            return status;
-        }
-        return CodeStatus.UNFINISHED;
-    }
-    
-    private CodeStatus selectChild( int index, Memory m  )
-    {
-        switch( ( (PseudoCodeNode)children.get( index ) ).setSelected( true ) )
-        {
-        case CONTINUE:
-            return CodeStatus.UNFINISHED;
-        case SKIP:
-            switch( ( (PseudoCodeNode)children.get( index ) ).forwardStepOverIntern( m ) )
-            {
-            case BREAKPOINT:
-                return CodeStatus.BREAKPOINT;
-            case FINISHED:
-                return childNodeFinished( m );
-            case UNFINISHED:
-            	throw new IllegalStateException( "Skipping a node returned UNFINISHED" );
-            }
-        case STOP:
-            return CodeStatus.BREAKPOINT;
-        }
-        return CodeStatus.UNFINISHED;
-    }
-
-    /**
-     * Perform steps until the next line of code on the same level of indentation as this line
-     * is reached. Stops at the end of the program.
-     * @return whether the whole stage is finished (afterwards).
-     * For example if all steps are finished, then {@code FINISHED} is returned.
-     */
-    public CodeStatus forwardStepOver( Memory m )
-    {
-        switch( getForwardNode().forwardStepOverIntern( m ) )
-        {
-		case BREAKPOINT:
-			return CodeStatus.BREAKPOINT;
-		case FINISHED:
-			if( getForwardNode() == this )
-				return CodeStatus.FINISHED;
-			else
-				return childNodeFinished( m );
-		case UNFINISHED:
-			return CodeStatus.UNFINISHED;
-        }
-		return CodeStatus.UNFINISHED;
-    }
-    
-    private CodeStatus forwardStepOverIntern( Memory m )
-    {
-        CodeStatus status = null;
-        do {
-        	PseudoCodeNode af = alg.getActiveFunction();
-            status = forwardStep( m );
-            if( status == CodeStatus.UNFINISHED && af != alg.getActiveFunction() )
-            {
-            	switch( alg.getActiveFunction().forwardStepOverIntern( m ) )
-            	{
-				case BREAKPOINT:
-					return CodeStatus.BREAKPOINT;
-				case FINISHED:
-					break;
-				case UNFINISHED:
-					throw new IllegalStateException( "StepOver did not return finished" );
-            	}
-            }
-        } while( status == CodeStatus.UNFINISHED );
-        return status;
-    }
-
-    /**
-     * Perform steps until the next line of code on the level of indentation above this lines 
-     * level is reached. Stops at the end of the program.
-     * @return whether the whole stage is finished (afterwards).
-     * For example if all steps are finished, then {@code FINISHED} is returned.
-     */
-    public CodeStatus forwardStepOut( Memory m )
-    {
-        switch( getForwardNode().forwardStepOutIntern( m ) )
-        {
-		case BREAKPOINT:
-			return CodeStatus.BREAKPOINT;
-		case FINISHED:
-			if( getForwardNode() == this )
-				return CodeStatus.FINISHED;
-			else
-				return childNodeFinished( m );
-		case UNFINISHED:
-	        return CodeStatus.UNFINISHED;
-        }
-        return CodeStatus.UNFINISHED;
-    }
-    
-    private CodeStatus forwardStepOutIntern( Memory m )
+    public ControlFlow forwardStep( Memory m )
     {
-        if( parent != null && !alg.isActiveFunction( this ) )
-            return ((PseudoCodeNode)parent).forwardStepOverIntern( m );
-        return forwardStepOverIntern( m );
+        return code.runForward( m );
     }
     
-    /**
-     * Undo one atomic step of the algorithm. Stops at the beginning of the program.
-     * @return whether the whole stage is finished in backwards direction (afterwards).
-     * For example if all steps have been reverted, then {@code FINISHED} is returned.
-     */
-    public CodeStatus backwardStep( Memory m )
+    public ControlFlow backwardStep( Memory m )
     {
-        // TODO
-        return null;
+        return code.runBackward( m );
     }
-
-    /**
-     * Perform backward steps until the previous line of code on the same level of indentation 
-     * as this line is reached. Stops at the end of the program.
-     * @return whether the whole stage is finished in backwards direction (afterwards).
-     * For example if all steps have been reverted, then {@code FINISHED} is returned.
-     */
-    public CodeStatus backwardStepOver( Memory m )
-    {
-        return getBackwardNode().backwardStepOverIntern( m );
-    }
-    
-    private CodeStatus backwardStepOverIntern( Memory m )
-    {
-        CodeStatus status = null;
-        do {
-            status = backwardStep( m );
-        } while( status == CodeStatus.UNFINISHED );
-        return status;
-    }
-
-
-    /**
-     * Perform backward steps until the previous line of code on the level of indentation above 
-     * this lines level is reached. Stops at the end of the program.
-     * @return whether the whole stage is finished in backwards direction (afterwards).
-     * For example if all steps have been reverted, then {@code FINISHED} is returned.
-     */
-    public CodeStatus backwardStepOut( Memory m )
-    {
-        return getBackwardNode().backwardStepOutIntern( m );
-    }
-    
-    private CodeStatus backwardStepOutIntern( Memory m )
-    {
-        if( parent != null )
-            return ((PseudoCodeNode)parent).backwardStepOver( m );
-        return backwardStepOutIntern( m );
-    }
-    
-    protected void hiddenActionWithoutSideEffects( Memory m ) {}
 }

+ 184 - 0
src/animation/PseudoCodeProcessor.java

@@ -0,0 +1,184 @@
+package animation;
+
+import animation.Memory.MemoryType;
+import animation.StackFrame.FrameType;
+
+public class PseudoCodeProcessor {
+
+    public static enum CodeStatus
+    {
+        UNFINISHED,
+        BREAKPOINT,
+        FINISHED
+    }
+    
+    private Memory mem;
+    private PseudoCodeNode programPointer;
+    
+    public PseudoCodeProcessor( PseudoCodeNode tree )
+    {
+        mem = new Memory();
+        mem.addFrame( new StackFrame( FrameType.FUNCTION ) );
+        programPointer = tree;
+    }
+    
+    private CodeStatus selectNextNode( PseudoCodeNode next, PseudoCodeNode last )
+    {
+        programPointer = next;
+        last.setSelected( false );
+        switch( next.setSelected( true ) )
+        {
+        case CONTINUE:
+            return CodeStatus.UNFINISHED;
+        case SKIP:
+            return forwardStepOver();
+        case STOP:
+            return CodeStatus.BREAKPOINT;
+        }
+        return CodeStatus.UNFINISHED;
+    }
+    
+    public CodeStatus forwardStep()
+    {
+        if( programPointer == null )
+            return CodeStatus.FINISHED;
+        StackFrame before = mem.removeFrame();
+        mem.addFrame( before );
+        ControlFlow cf = programPointer.forwardStep( mem );
+        switch( cf.getStatus() )
+        {
+        case ControlFlow.STEP_INTO:
+            if( mem.isDefined( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ) )
+            {
+                mem.declare( "_returnTo" + programPointer, mem.read( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ), MemoryType.LOCAL );
+                mem.undeclare( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL );
+            }
+            if( programPointer.children() == null )
+                throw new IllegalStateException( "A Codeline without sublines tryd to make a STEP_INTO." );
+            else
+                return selectNextNode( (PseudoCodeNode)programPointer.getFirstChild(), programPointer );
+        case ControlFlow.STEP_OVER:
+            if( programPointer.getParent() == null )
+                return CodeStatus.FINISHED;
+            if( before.isDefined( "_returnTo" + programPointer.getId() ) )
+            {
+                PseudoCodeNode nextPC = before.<PseudoCodeNode>get( "_returnTo" + programPointer.getId() );
+                before.undeclare( "_returnTo" + programPointer.getId() );
+                return selectNextNode( nextPC, programPointer );
+            }
+            PseudoCodeNode nextPC = (PseudoCodeNode) ((PseudoCodeNode)programPointer.getParent()).getChildAfter( programPointer );
+            if( nextPC == null )
+                return selectNextNode( (PseudoCodeNode)programPointer.getParent(), programPointer );
+            else
+                return selectNextNode( nextPC, programPointer );
+        case ControlFlow.CALL:
+            mem.declare( "_returnTo" + cf.getFunction().getId(), programPointer, MemoryType.GLOBAL );
+            return selectNextNode( cf.getFunction(), programPointer );
+        }
+        throw new IllegalStateException( "Unbekannte ControlFlow Aktion" );
+    }
+    
+    public CodeStatus forwardStepOver()
+    {
+        if( programPointer == null )
+            return CodeStatus.FINISHED;
+        int stackSize = mem.getSize();
+        CodeStatus status = CodeStatus.UNFINISHED;
+        do {
+            status = forwardStep();
+        } while( mem.getSize() > stackSize && status == CodeStatus.UNFINISHED );
+        return status;
+    }
+    
+    public CodeStatus forwardStepOut()
+    {
+        if( programPointer == null )
+            return CodeStatus.FINISHED;
+        int stackSize = mem.getSize();
+        CodeStatus status = CodeStatus.UNFINISHED;
+        do {
+            status = forwardStep();
+        } while( mem.getSize() >= stackSize && status == CodeStatus.UNFINISHED );
+        return status;
+    }
+    
+    private CodeStatus selectBeforeNode( PseudoCodeNode next, PseudoCodeNode last )
+    {
+        programPointer = next;
+        last.setSelected( false );
+        switch( next.setSelected( true ) )
+        {
+        case CONTINUE:
+            return CodeStatus.UNFINISHED;
+        case SKIP:
+            return backwardStepOver();
+        case STOP:
+            return CodeStatus.BREAKPOINT;
+        }
+        return CodeStatus.UNFINISHED;
+    }
+    
+    public CodeStatus backwardStep()
+    {
+        if( programPointer == null )
+            return CodeStatus.FINISHED;
+        StackFrame before = mem.removeFrame();
+        mem.addFrame( before );
+        ControlFlow cf = programPointer.backwardStep( mem );
+        switch( cf.getStatus() )
+        {
+        case ControlFlow.STEP_INTO:
+            if( mem.isDefined( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ) )
+            {
+                mem.declare( "_returnTo" + programPointer, mem.read( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ), MemoryType.LOCAL );
+                mem.undeclare( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL );
+            }
+            if( programPointer.children() == null )
+                throw new IllegalStateException( "A Codeline without sublines tryd to make a STEP_INTO." );
+            else
+                return selectBeforeNode( (PseudoCodeNode)programPointer.getLastChild(), programPointer );
+        case ControlFlow.STEP_OVER:
+            if( programPointer.getParent() == null )
+                return CodeStatus.FINISHED;
+            if( before.isDefined( "_returnTo" + programPointer.getId() ) )
+            {
+                PseudoCodeNode nextPC = before.<PseudoCodeNode>get( "_returnTo" + programPointer.getId() );
+                before.undeclare( "_returnTo" + programPointer.getId() );
+                return selectBeforeNode( nextPC, programPointer );
+            }
+            PseudoCodeNode nextPC = (PseudoCodeNode) ((PseudoCodeNode)programPointer.getParent()).getChildBefore( programPointer );
+            if( nextPC == null )
+                return selectBeforeNode( (PseudoCodeNode) programPointer.getParent(), programPointer );
+            else
+                return selectBeforeNode( nextPC, programPointer );
+        case ControlFlow.CALL:
+            mem.declare( "_returnTo" + cf.getFunction().getId(), programPointer, MemoryType.GLOBAL );
+            return selectBeforeNode( cf.getFunction(), programPointer );
+        }
+        throw new IllegalStateException( "Unbekannte ControlFlow Aktion" );
+    }
+    
+    public CodeStatus backwardStepOver()
+    {
+        if( programPointer == null )
+            return CodeStatus.FINISHED;
+        int stackSize = mem.getSize();
+        CodeStatus status = CodeStatus.UNFINISHED;
+        do {
+            status = backwardStep();
+        } while( mem.getSize() > stackSize && status == CodeStatus.UNFINISHED );
+        return status;
+    }
+    
+    public CodeStatus backwardStepOut()
+    {
+        if( programPointer == null )
+            return CodeStatus.FINISHED;
+        int stackSize = mem.getSize();
+        CodeStatus status = CodeStatus.UNFINISHED;
+        do {
+            status = backwardStep();
+        } while( mem.getSize() >= stackSize && status == CodeStatus.UNFINISHED );
+        return status;
+    }
+}

+ 4 - 3
src/bk/BKNodePlacement.java

@@ -9,6 +9,7 @@ import animation.CodeLine;
 import animation.ControlFlow;
 import animation.Memory;
 import animation.PseudoCodeNode;
+import animation.PseudoCodeProcessor;
 import animation.Memory.MemoryType;
 import codelines.FunctionCall;
 import codelines.FunctionDefinition;
@@ -73,14 +74,14 @@ public class BKNodePlacement extends AnimatedAlgorithm {
 			@Override
 			public ControlFlow runForward(Memory m) {
 				m.declare( "param1", graph, MemoryType.GLOBAL );
-				if( m.isDefined( "Called", MemoryType.LOCAL ) )
+				if( m.isDefined( "Called", MemoryType.GLOBAL ) )
 				{
 					actions.push( (Memory mem) -> {
 						return new ControlFlow( mainFunction );
 					} );
 					return new ControlFlow( ControlFlow.STEP_OVER );
 				}
-				m.declare( "Called", true, MemoryType.LOCAL );
+				m.declare( "Called", true, MemoryType.GLOBAL );
 				actions.push( (Memory mem) -> {
 					return new ControlFlow( ControlFlow.STEP_OVER );
 				} );
@@ -95,7 +96,7 @@ public class BKNodePlacement extends AnimatedAlgorithm {
         root.add( mainFunction );
         mainFunction.add( node1 );
         root.add( conflictDetectionFunction );
-        this.addActiveFunction( root );
+        processor = new PseudoCodeProcessor( root );
         return root;
     }
 

+ 4 - 4
src/bk/ConflictDetection.java

@@ -12,7 +12,6 @@ import animation.ControlFlow;
 import animation.Memory;
 import animation.PseudoCodeNode;
 import animation.Memory.MemoryType;
-import bk.BKNodePlacement.State;
 import bk.ExtremalLayoutCalc.LayoutType;
 import codelines.DeclareVariable;
 import codelines.ForEachLoop;
@@ -47,7 +46,7 @@ public class ConflictDetection implements AlgorithmStage {
         String params[] = { "graph" };
         @SuppressWarnings("serial")
         PseudoCodeNode root = new PseudoCodeNode(TextLayoutHelper.setupPseudoCode("function mark_conflicts( graph )", vars), tree, new FunctionDefinition( params ), alg ) {
-            @Override
+            /*@Override
             protected void hiddenActionWithoutSideEffects( Memory m )
             {
                 ((BKNodePlacement)alg).setState( State.CONFLICTS );
@@ -75,7 +74,7 @@ public class ConflictDetection implements AlgorithmStage {
                 {
                     m.<LayeredGraphNode>read( "n", MemoryType.LOCAL ).setSelected( null );
                 }
-            }
+            }*/
         };
         PseudoCodeNode text = new PseudoCodeNode(TextLayoutHelper.setupPseudoCodeStage( "-- mark conflicts in subgrapfhs --" ), tree, new Kommentar(), alg );
         root.add( text );
@@ -250,6 +249,7 @@ public class ConflictDetection implements AlgorithmStage {
         String k1 = "null";
         String v = "null";
         String n = "null";
+        /*
         if( alg.getMemory().isSomewhereDefined( "i", MemoryType.LOCAL ) )
             i = "" + alg.getMemory().<Integer>read( "i", MemoryType.LOCAL );
         if( alg.getMemory().isSomewhereDefined( "l", MemoryType.LOCAL ) )
@@ -263,7 +263,7 @@ public class ConflictDetection implements AlgorithmStage {
         if( alg.getMemory().isSomewhereDefined( "v", MemoryType.LOCAL ) && alg.getMemory().<LayeredGraphEdge>read( "v", MemoryType.LOCAL ).getSources().get( 0 ).getName() != null )
             v = "" + alg.getMemory().<LayeredGraphEdge>read( "v", MemoryType.LOCAL ).getSources().get( 0 ).getName();
         if( alg.getMemory().isSomewhereDefined( "n", MemoryType.LOCAL ) && alg.getMemory().<LayeredGraphNode>read( "n", MemoryType.LOCAL ).getName() != null )
-            n = "" + alg.getMemory().<LayeredGraphNode>read( "n", MemoryType.LOCAL ).getName();
+            n = "" + alg.getMemory().<LayeredGraphNode>read( "n", MemoryType.LOCAL ).getName();*/
         info += "|" + TextLayoutHelper.strToLen( i, 4 ) + 
                 "|" + TextLayoutHelper.strToLen( l, 4 ) + 
                 "|" + TextLayoutHelper.strToLen( l1, 4 ) +