浏览代码

Merge remote-tracking branch 'origin/EvenBetterStructure' into BetterStructure

# Conflicts:
#	src/bk/ConflictDetection.java
Eren Yilmaz 6 年之前
父节点
当前提交
ea6f0687c2

+ 0 - 7
src/animation/AlgorithmStage.java

@@ -25,11 +25,4 @@ public interface AlgorithmStage {
      * @return The node.
      */
     public PseudoCodeNode createPseudocodeTree( JTree tree );
-    
-    /**
-     * Writes the state of the variables used in this stage to a pretty table.
-     * This table should also render nicely if interpreted as markdown. 
-     * @return the table
-     */
-    public String getDebugString();
 }

+ 35 - 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,20 +79,19 @@ 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 );
             }
         }
     }
 
     @Override
     public abstract PseudoCodeNode createPseudocodeTree( JTree tree );
+    
+    public String getDebugString()
+    {
+        if( processor == null )
+            return "";
+        return processor.getDebugOutput();
+    }
 }

+ 4 - 5
src/animation/CodeLine.java

@@ -6,7 +6,7 @@ public abstract class CodeLine {
 
 	protected interface BackwardAction
 	{
-		public ControlFlow backward( Memory m );
+		public void backward( Memory m );
 	}
 	
 	protected Stack<BackwardAction> actions;
@@ -23,10 +23,9 @@ public abstract class CodeLine {
 	
     public abstract ControlFlow runForward( Memory m );
     
-    public ControlFlow runBackward( Memory m )
+    public void runBackward( Memory m )
     {
-    	if( actions.size() == 0 )
-    		return new ControlFlow( ControlFlow.STEP_OVER );
-    	return actions.pop().backward( m );
+    	if( actions.size() != 0 )
+    	    actions.pop().backward( m );
     }
 }

+ 37 - 2
src/animation/ControlFlow.java

@@ -1,5 +1,7 @@
 package animation;
 
+import animation.CodeLine.BackwardAction;
+
 public class ControlFlow {
     public static final int STEP_INTO = 0;
     public static final int STEP_OVER = 1;
@@ -7,24 +9,57 @@ public class ControlFlow {
     
     private int status;
     private PseudoCodeNode function;
+    private PseudoCodeNode jumpBack;
+    private BackwardAction reverse;
     
     public ControlFlow( int status )
     {
         this.status = status;
+        function = null;
+        jumpBack = null;
+        reverse = null;
     }
     
     public ControlFlow( PseudoCodeNode functionNode )
     {
     	status = CALL;
     	function = functionNode;
+        jumpBack = null;
+        reverse = null;
+    }
+    
+    /*
+     * Package Private from here on
+     * This is wanted because the individual algorithms should not have access to these functions
+     */
+    
+    void setJumpBack( PseudoCodeNode jB )
+    {
+        jumpBack = jB;
+    }
+    
+    void setBackwardAction( BackwardAction bka )
+    {
+        reverse = bka;
+    }
+    
+    void backward( Memory m )
+    {
+        if( reverse != null )
+            reverse.backward( m );
+    }
+    
+    PseudoCodeNode getJumpBack()
+    {
+        return jumpBack;
     }
     
-    public PseudoCodeNode getFunction()
+    PseudoCodeNode getFunction()
     {
     	return function;
     }
     
-    public int getStatus()
+    int getStatus()
     {
         return status;
     }

+ 1 - 78
src/animation/Memory.java

@@ -9,11 +9,9 @@ public class Memory {
     public enum MemoryType
     {
         GLOBAL,
-        LOCAL,
-        CURRENT
+        LOCAL
     }
     
-    private StackFrame current;
     private StackFrame global;
     private Stack< StackFrame > stack;
     
@@ -21,7 +19,6 @@ public class Memory {
     {
         stack = new Stack<StackFrame>();
         global = new StackFrame( FrameType.FUNCTION );
-        current = null;
     }
     
     public int getSize()
@@ -29,11 +26,6 @@ public class Memory {
         return stack.size();
     }
     
-    public void setCurrent( StackFrame frame )
-    {
-        this.current = frame;
-    }
-    
     public void addFrame( StackFrame frame )
     {
         stack.push( frame );
@@ -51,10 +43,6 @@ public class Memory {
         case GLOBAL:
             this.global.declare( name, value );
             break;
-        case CURRENT:
-            if( current != null )
-                current.declare( name, value );
-            break;
         case LOCAL:
         	if( stack.size() == 0 )
         		return;
@@ -70,27 +58,6 @@ public class Memory {
         case GLOBAL:
             this.global.set( name, value );
             break;
-        case CURRENT:
-            if( current != null )
-            {
-                int index = stack.size() - 1;
-                while( index >= 0 && stack.get( index ) != current ) {
-                    index--;
-                }
-                if( index < 0 )
-                    break;
-                while( index >= 0 ) {
-                    StackFrame stackF = stack.get( index-- );
-                    if( stackF.isDefined( name ) )
-                    {
-                        stackF.set( name, value );
-                        return;
-                    }
-                    if( stackF.getType() == FrameType.FUNCTION )
-                        break;
-                 }
-            }
-            break;
         case LOCAL:
         	int index = stack.size() - 1;
         	while( index >= 0 ) {
@@ -112,24 +79,6 @@ public class Memory {
         {
         case GLOBAL:
             return this.global.get( name );
-        case CURRENT:
-            if( current != null )
-            {
-                int index = stack.size() - 1;
-                while( index >= 0 && stack.get( index ) != current ) {
-                    index--;
-                }
-                if( index < 0 )
-                    break;
-                while( index >= 0 ) {
-                    StackFrame stackF = stack.get( index-- );
-                    if( stackF.isDefined( name ) )
-                        return stackF.get( name );
-                    if( stackF.getType() == FrameType.FUNCTION )
-                        break;
-                 }
-            }
-            break;
         case LOCAL:
             int index = stack.size() - 1;
             while( index >= 0 ) {
@@ -149,24 +98,6 @@ public class Memory {
         {
         case GLOBAL:
             return this.global.isDefined( name );
-        case CURRENT:
-            if( current != null )
-            {
-                int index = stack.size() - 1;
-                while( index >= 0 && stack.get( index ) != current ) {
-                    index--;
-                }
-                if( index < 0 )
-                    break;
-                while( index >= 0 ) {
-                    StackFrame stackF = stack.get( index-- );
-                    if( stackF.isDefined( name ) )
-                        return true;
-                    if( stackF.getType() == FrameType.FUNCTION )
-                        break;
-                 }
-            }
-            break;
         case LOCAL:
             int index = stack.size() - 1;
             while( index >= 0 ) {
@@ -186,10 +117,6 @@ public class Memory {
         {
         case GLOBAL:
             return this.global.isDefined( name );
-        case CURRENT:
-            if( current != null)
-                return current.isDefined( name );
-            return false;
         case LOCAL:
             if( stack.size() == 0 )
                 return false;
@@ -205,10 +132,6 @@ public class Memory {
         case GLOBAL:
             this.global.undeclare( name );
             break;
-        case CURRENT:
-            if( current != null )
-                current.undeclare( name );
-            break;
         case LOCAL:
         	if( stack.size() == 0 )
         		return;

+ 21 - 380
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,33 +19,20 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
         STOP,
         CONTINUE
     }
-
-    public static enum CodeStatus
-    {
-        UNFINISHED,
-        BREAKPOINT,
-        FINISHED
-    }
     
     private static final long serialVersionUID = 1L;
 
     private static int nextNodeId = 0;
     private final int nodeId;
     private AnimationController controller;
-    private AnimatedAlgorithm alg;
     private JTree tree;
     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 )
+    public PseudoCodeNode( String description, JTree tree, CodeLine line )
     {
         super( description );
-        this.alg = alg;
         synchronized( PseudoCodeNode.class )
         {
         	nodeId = nextNodeId++;
@@ -55,10 +40,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 +60,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 +169,30 @@ 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 )
+    public ControlFlow forwardStep( 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;
+        ControlFlow cf = code.runForward( m );
+        cf.setJumpBack( this );
+        return cf;
     }
     
-    private CodeStatus forwardStepOverIntern( Memory m )
+    public ControlFlow emptyForwardStep( 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;
+        code.actions.push( (Memory mem) -> {} ); // add empty reverse function
+        ControlFlow cf = new ControlFlow( ControlFlow.STEP_OVER );
+        cf.setJumpBack( this );
+        return cf;
     }
     
-    private CodeStatus forwardStepOutIntern( Memory m )
+    public void backwardStep( Memory m )
     {
-        if( parent != null && !alg.isActiveFunction( this ) )
-            return ((PseudoCodeNode)parent).forwardStepOverIntern( m );
-        return forwardStepOverIntern( m );
+        code.runBackward( 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 )
-    {
-        // TODO
-        return null;
-    }
-
-    /**
-     * 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 )
+    public String getDebugOutput( Memory m )
     {
-        return getBackwardNode().backwardStepOverIntern( m );
+        if( parent == null )
+            return "";
+        return ((PseudoCodeNode)parent).getDebugOutput( 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 ) {}
 }

+ 192 - 0
src/animation/PseudoCodeProcessor.java

@@ -0,0 +1,192 @@
+package animation;
+
+import java.util.Stack;
+
+import animation.Memory.MemoryType;
+import animation.StackFrame.FrameType;
+
+public class PseudoCodeProcessor {
+
+    public static enum CodeStatus
+    {
+        UNFINISHED,
+        BREAKPOINT,
+        FINISHED
+    }
+    
+    private String currentDebugOutput;
+    private Memory mem;
+    private PseudoCodeNode programPointer;
+    private Stack<ControlFlow> controlStack;
+    
+    public PseudoCodeProcessor( PseudoCodeNode tree )
+    {
+        mem = new Memory();
+        mem.addFrame( new StackFrame( FrameType.FUNCTION ) );
+        programPointer = tree;
+        currentDebugOutput = "";
+        controlStack = new Stack<>();
+    }
+    
+    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 = null;
+        if( mem.isDefined( "_call" + programPointer.getId(), MemoryType.LOCAL ) )
+        {
+            mem.undeclare( "_call" + programPointer.getId(), MemoryType.LOCAL );
+            cf = programPointer.emptyForwardStep( mem );
+            cf.setBackwardAction( (Memory m) -> {
+                mem.declare( "_call" + programPointer.getId(), true, MemoryType.LOCAL );
+            });
+        }
+        else
+            cf = programPointer.forwardStep( mem );
+        controlStack.push( cf );
+        currentDebugOutput = programPointer.getDebugOutput( mem );
+        switch( cf.getStatus() )
+        {
+        case ControlFlow.STEP_INTO:
+            if( mem.isDefined( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ) )
+            {
+                mem.declare( "_returnTo" + programPointer.getId(), mem.read( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ), MemoryType.LOCAL );
+                mem.undeclare( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL );
+                cf.setBackwardAction( (Memory m) -> {
+                    mem.declare( "_returnTo" + programPointer.getId(), mem.read( "_returnTo" + programPointer.getId(), MemoryType.LOCAL ), MemoryType.GLOBAL );
+                    mem.undeclare( "_returnTo" + programPointer.getId(), MemoryType.LOCAL );
+                });
+            }
+            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() );
+                cf.setBackwardAction( (Memory m) -> {
+                    before.declare( "_returnTo" + programPointer.getId(), nextPC );
+                });
+                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:
+            PseudoCodeNode f = cf.getFunction();
+            mem.declare( "_call" + programPointer.getId(), true, MemoryType.LOCAL );
+            mem.declare( "_returnTo" + f.getId(), cf.getJumpBack(), MemoryType.GLOBAL );
+            cf.setBackwardAction( (Memory m) -> {
+                m.undeclare( "_returnTo" + f.getId(), MemoryType.GLOBAL );
+                m.undeclare( "_call" + programPointer.getId(), MemoryType.LOCAL );
+            });
+            return selectNextNode( f, 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 || controlStack.isEmpty() )
+            return CodeStatus.FINISHED;
+        ControlFlow cf = controlStack.pop();
+        PseudoCodeNode nextPC = cf.getJumpBack();
+        cf.backward( mem );
+        nextPC.backwardStep( mem );
+        currentDebugOutput = nextPC.getDebugOutput( mem );
+        return selectBeforeNode( nextPC, programPointer );
+    }
+    
+    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;
+    }
+    
+    public String getDebugOutput()
+    {
+        return currentDebugOutput;
+    }
+}

+ 14 - 47
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;
@@ -22,10 +23,6 @@ import lib.TextLayoutHelper;
  */
 public class BKNodePlacement extends AnimatedAlgorithm {
 
-    /*
-     * Private data structures to store the process of the algorithm
-     */
-
     public enum State
     {
         CONFLICTS,
@@ -35,22 +32,12 @@ public class BKNodePlacement extends AnimatedAlgorithm {
         LAYOUT4,
         COMBINE
     }
-
-    private ConflictDetection conftion;
+    
     private State state;
-    private ExtremalLayoutCalc layouts[];
-    private Combine combine;
-
+    
     public BKNodePlacement(AnimationController controller, LayeredGraphNode graph, JFrame view) {
         super(controller, graph, view);
         state = State.CONFLICTS;
-        conftion = new ConflictDetection( this );
-        layouts = new ExtremalLayoutCalc[ 4 ];
-        layouts[ 0 ] = new ExtremalLayoutCalc( this );
-        layouts[ 1 ] = new ExtremalLayoutCalc( this );
-        layouts[ 2 ] = new ExtremalLayoutCalc( this );
-        layouts[ 3 ] = new ExtremalLayoutCalc( this );
-        combine = new Combine( this );
     }
     
     public State getAlgorithmState()
@@ -58,7 +45,7 @@ public class BKNodePlacement extends AnimatedAlgorithm {
         return state;
     }
     
-    public void setState( State s )
+    public void setAlgorithmState( State s )
     {
         state = s;
     }
@@ -67,56 +54,36 @@ public class BKNodePlacement extends AnimatedAlgorithm {
     public PseudoCodeNode createPseudocodeTree( JTree tree )
     {
     	String[] vars = { "graph" };
-    	PseudoCodeNode mainFunction = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode("function bkNodePlacement( graph )", vars ), tree, new FunctionDefinition( new String[]{"graph"} ), this );
+    	PseudoCodeNode mainFunction = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode("function bkNodePlacement( graph )", vars ), tree, new FunctionDefinition( new String[]{"graph"} ) );
     	root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCodeStage("-- BK Node Placement Algorithm --" ), tree, new CodeLine() {
 
 			@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 );
+					    m.undeclare( "param1", MemoryType.GLOBAL );
 					} );
 					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 );
+                    m.undeclare( "param1", MemoryType.GLOBAL );
+	                m.undeclare( "Called", MemoryType.GLOBAL );
 				} );
 				return new ControlFlow( mainFunction );
 			}
         	
-        }, this );
+        } );
         root.setSelected( true );
     	
-        PseudoCodeNode conflictDetectionFunction = conftion.createPseudocodeTree( tree );
-        PseudoCodeNode node1 = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "call detectConflicts( graph )", vars ), tree, new FunctionCall( conflictDetectionFunction, new String[]{ "graph" } ), this );
+        PseudoCodeNode conflictDetectionFunction = new ConflictDetection( this ).createPseudocodeTree( tree );
+        PseudoCodeNode node1 = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "call detectConflicts( graph )", vars ), tree, new FunctionCall( conflictDetectionFunction, new String[]{ "graph" } ) );
         root.add( mainFunction );
         mainFunction.add( node1 );
         root.add( conflictDetectionFunction );
-        this.addActiveFunction( root );
+        processor = new PseudoCodeProcessor( root );
         return root;
     }
-
-    @Override
-    public String getDebugString()
-    {
-        switch( state )
-        {
-        case CONFLICTS:
-            return conftion.getDebugString();
-        case LAYOUT1:
-            return layouts[ 0 ].getDebugString();
-        case LAYOUT2:
-            return layouts[ 1 ].getDebugString();
-        case LAYOUT3:
-            return layouts[ 2 ].getDebugString();
-        case LAYOUT4:
-            return layouts[ 3 ].getDebugString();
-        case COMBINE:
-            return combine.getDebugString();
-        }
-        return "";
-    }
 }

+ 1 - 16
src/bk/BlockCalc.java

@@ -18,32 +18,17 @@ import lib.TextLayoutHelper;
  */
 public class BlockCalc implements AlgorithmStage {
 
-    private AnimatedAlgorithm alg;
-
-    public BlockCalc( AnimatedAlgorithm alg  )
-    {
-        this.alg = alg;
-    }
-
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
         String[] vars = { "graph", "L", "v", "r", "neighbors" };
         PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "calculateBlockGraph( graph )", vars ), tree, new CodeLine() {
-
-        	private LayeredGraphNode param;
         	
 			@Override
 			public ControlFlow runForward(Memory m) {
 				return new ControlFlow( ControlFlow.STEP_INTO );
 			}
         	
-        }, alg);
+        } );
         return root;
     }
-    
-    @Override
-    public String getDebugString()
-    {
-        return "";
-    }
 }

+ 1 - 17
src/bk/Combine.java

@@ -3,7 +3,6 @@ package bk;
 import javax.swing.JTree;
 
 import animation.AlgorithmStage;
-import animation.AnimatedAlgorithm;
 import animation.CodeLine;
 import animation.ControlFlow;
 import animation.Memory;
@@ -17,13 +16,6 @@ import lib.TextLayoutHelper;
  */
 public class Combine implements AlgorithmStage {
 
-    private AnimatedAlgorithm alg;
-
-    public Combine( AnimatedAlgorithm alg )
-    {
-        this.alg = alg;
-    }
-
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
         PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCodeStage("Balancing"), tree, new CodeLine() {
@@ -34,15 +26,7 @@ public class Combine implements AlgorithmStage {
 				return null;
 			}
         	
-        }, alg );
+        } );
         return root;
     }
-    
-    @Override
-    public String getDebugString()
-    {
-        String info = "| Node |  x  | x LU | x RU | x LL | x RL |\n";
-        info +=       "|------|-----|------|------|------|------|\n";
-        return info;
-    }
 }

+ 2 - 17
src/bk/Compaction.java

@@ -3,7 +3,6 @@ package bk;
 import javax.swing.JTree;
 
 import animation.AlgorithmStage;
-import animation.AnimatedAlgorithm;
 import animation.CodeLine;
 import animation.ControlFlow;
 import animation.Memory;
@@ -15,15 +14,7 @@ import lib.TextLayoutHelper;
  * @author kolja
  *
  */
-public class Compaction implements AlgorithmStage{
-
-    private AnimatedAlgorithm alg;
-
-
-    public Compaction( AnimatedAlgorithm alg )
-    {
-        this.alg = alg;
-    }
+public class Compaction implements AlgorithmStage {
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
@@ -34,13 +25,7 @@ public class Compaction implements AlgorithmStage{
 				return null;
 			}
         	
-        }, alg );
+        } );
         return root;
     }
-    
-    @Override
-    public String getDebugString()
-    {
-        return "";
-    }
 }

+ 59 - 68
src/bk/ConflictDetection.java

@@ -6,7 +6,6 @@ import java.util.List;
 import javax.swing.JTree;
 
 import animation.AlgorithmStage;
-import animation.AnimatedAlgorithm;
 import animation.CodeLine;
 import animation.ControlFlow;
 import animation.Memory;
@@ -35,23 +34,23 @@ import lib.TextLayoutHelper;
  */
 public class ConflictDetection implements AlgorithmStage {
 
-    private AnimatedAlgorithm alg;
-
-    public ConflictDetection( AnimatedAlgorithm alg ) {
-        this.alg = alg;
+    private BKNodePlacement alg;
+    
+    public ConflictDetection( BKNodePlacement bknpa )
+    {
+        alg = bknpa;
     }
-
+    
     @Override
     public PseudoCodeNode createPseudocodeTree(JTree tree) {
         String vars[] = { "i", "L", "k0", "l", "l1", "k1", "v", "graph", "n" };
         String params[] = { "graph" };
         @SuppressWarnings("serial")
-        PseudoCodeNode root = new PseudoCodeNode(TextLayoutHelper.setupPseudoCode("function mark_conflicts( graph )", vars), tree, new FunctionDefinition( params ), alg ) {
+        PseudoCodeNode root = new PseudoCodeNode(TextLayoutHelper.setupPseudoCode("function mark_conflicts( graph )", vars), tree, new FunctionDefinition( params ) ) {
             @Override
-            protected void hiddenActionWithoutSideEffects( Memory m )
+            public String getDebugOutput( Memory m )
             {
-                ((BKNodePlacement)alg).setState( State.CONFLICTS );
-                
+                alg.setAlgorithmState( State.CONFLICTS );
                 if( m.isSomewhereDefined( "l", MemoryType.LOCAL ) && m.isSomewhereDefined( "i", MemoryType.LOCAL ) && 
                         m.<Integer>read( "l", MemoryType.LOCAL ) < m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL).getContainedLayers().get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 ).size() )
                     m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL).getContainedLayers().get(m.<Integer>read( "i", MemoryType.LOCAL ) + 1).get(m.<Integer>read( "l", MemoryType.LOCAL )).setSelected(null);
@@ -75,27 +74,58 @@ public class ConflictDetection implements AlgorithmStage {
                 {
                     m.<LayeredGraphNode>read( "n", MemoryType.LOCAL ).setSelected( null );
                 }
+                String info = "| i  | l  | l1 | k0 | k1 |  v  |  n  |\n";
+                info +=       "|----|----|----|----|----|-----|-----|\n";
+                String i = "null";
+                String l = "null";
+                String l1 = "null";
+                String k0 = "null";
+                String k1 = "null";
+                String v = "null";
+                String n = "null";
+                if( m.isSomewhereDefined( "i", MemoryType.LOCAL ) )
+                    i = "" + m.<Integer>read( "i", MemoryType.LOCAL );
+                if( m.isSomewhereDefined( "l", MemoryType.LOCAL ) )
+                    l = "" + m.<Integer>read( "l", MemoryType.LOCAL );
+                if( m.isSomewhereDefined( "l1", MemoryType.LOCAL ) )
+                    l1 = "" + m.<Integer>read( "l1", MemoryType.LOCAL );
+                if( m.isSomewhereDefined( "k0", MemoryType.LOCAL ) )
+                    k0 = "" + m.<Integer>read( "k0", MemoryType.LOCAL );
+                if( m.isSomewhereDefined( "k1", MemoryType.LOCAL ) )
+                    k1 = "" + m.<Integer>read( "k1", MemoryType.LOCAL );
+                if( m.isSomewhereDefined( "v", MemoryType.LOCAL ) && m.<LayeredGraphEdge>read( "v", MemoryType.LOCAL ).getSources().get( 0 ).getName() != null )
+                    v = "" + m.<LayeredGraphEdge>read( "v", MemoryType.LOCAL ).getSources().get( 0 ).getName();
+                if( m.isSomewhereDefined( "n", MemoryType.LOCAL ) && m.<LayeredGraphNode>read( "n", MemoryType.LOCAL ).getName() != null )
+                    n = "" + m.<LayeredGraphNode>read( "n", MemoryType.LOCAL ).getName();
+                info += "|" + TextLayoutHelper.strToLen( i, 4 ) + 
+                        "|" + TextLayoutHelper.strToLen( l, 4 ) + 
+                        "|" + TextLayoutHelper.strToLen( l1, 4 ) + 
+                        "|" + TextLayoutHelper.strToLen( k0, 4 ) + 
+                        "|" + TextLayoutHelper.strToLen( k1, 4 ) + 
+                        "|" + TextLayoutHelper.strToLen( v, 5 ) + 
+                        "|" + TextLayoutHelper.strToLen( n, 5 ) + "|\n";
+                return info;
             }
         };
-        PseudoCodeNode text = new PseudoCodeNode(TextLayoutHelper.setupPseudoCodeStage( "-- mark conflicts in subgraphs --" ), tree, new Kommentar(), alg );
+        PseudoCodeNode text = new PseudoCodeNode(TextLayoutHelper.setupPseudoCodeStage( "-- mark conflicts in subgrapfhs --" ), tree, new Kommentar() );
         root.add( text );
         PseudoCodeNode foreach = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "foreach n in graph.getContainedNodes() do", vars ), tree, new ForEachLoop<LayeredGraphNode>( "n" ) {
 			@Override
 			protected List<LayeredGraphNode> list(Memory m) {
 				return m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedNodes();
 			}
-        }, alg );
+        } );
         root.add( foreach );
         PseudoCodeNode ifNode = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if n has subgraph then", vars ), tree, new IfLoop() {
 			@Override
 			protected boolean condition(Memory m) {
 				return m.<LayeredGraphNode>read( "n", MemoryType.LOCAL ).getContainedLayers().size() > 0;
 			}
-        }, alg );
+        } );
         foreach.add( ifNode );
-        PseudoCodeNode call = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "call mark_conflicts( n );", vars ), tree, new FunctionCall( root, new String[]{ "n" } ), alg );
+        PseudoCodeNode call = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "call mark_conflicts( n );", vars ), tree, new FunctionCall( root, new String[]{ "n" } ) );
         ifNode.add( call );
-        text = new PseudoCodeNode(TextLayoutHelper.setupPseudoCodeStage( "-- mark conflicts in graph --" ), tree, new Kommentar(), alg );
+        text = new PseudoCodeNode(TextLayoutHelper.setupPseudoCodeStage( "-- mark conflicts in graph --" ), tree, new Kommentar() );
         root.add( text );
         PseudoCodeNode init = new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "L = graph.getContainedLayers();", vars), tree, new CodeLine() {
 			@Override
@@ -103,11 +133,10 @@ public class ConflictDetection implements AlgorithmStage {
 				m.declare( "L", m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedLayers(), MemoryType.LOCAL );
 				actions.push( (Memory mem) -> {
 					mem.undeclare( "L", MemoryType.LOCAL );
-					return new ControlFlow( ControlFlow.STEP_OVER );
 				} );
 				return new ControlFlow( ControlFlow.STEP_OVER );
 			}
-        }, alg );
+        } );
         root.add( init );
         PseudoCodeNode outerLoop = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "for i=1 to |L|-2 do", vars ), tree, new ForLoop( "i" ) {
 			@Override
@@ -118,7 +147,7 @@ public class ConflictDetection implements AlgorithmStage {
 			protected int maximum( Memory m ) {
 				return m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).size() - 2;
 			}
-        }, alg );
+        } );
         root.add( outerLoop );
         PseudoCodeNode line = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "k0 = 0; l = 0;", vars ), tree, new CodeLine() {
 			@Override
@@ -128,11 +157,10 @@ public class ConflictDetection implements AlgorithmStage {
 				actions.push( (Memory mem) -> {
 					mem.undeclare( "k0", MemoryType.LOCAL );
 					mem.undeclare( "l", MemoryType.LOCAL );
-					return new ControlFlow( ControlFlow.STEP_OVER );
 				} );
 				return new ControlFlow( ControlFlow.STEP_OVER );
 			}
-        }, alg );
+        } );
         outerLoop.add( line );
         PseudoCodeNode innerLoop = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "for l1=0 to |L[i+1]|-1 do", vars ), tree, new ForLoop( "l1" ) {
 			@Override
@@ -143,7 +171,7 @@ public class ConflictDetection implements AlgorithmStage {
 			protected int maximum(Memory m) {
 				return m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 ).size() - 1;
 			}
-        }, alg );
+        } );
         outerLoop.add( innerLoop );
         ifNode = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if l1==|L[i+1]|-1 or L[i+1][l1] incident to inner segment between L[i+1] and L[i] then", vars ), tree, new IfLoop() {
 			@Override
@@ -151,21 +179,21 @@ public class ConflictDetection implements AlgorithmStage {
 	            return m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedLayers().get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1).size() == m.<Integer>read( "l1", MemoryType.LOCAL ) || 
 	            		incidentToInnerSegmentBetweenLiPlusOneAndLi( m );
 			}
-        }, alg );
+        } );
         innerLoop.add( ifNode );
         line = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "k1 = |L[i]|-1;", vars ), tree, new DeclareVariable<Integer>( "k1" ) {
 			@Override
 			protected Integer value(Memory m) {
 				return (int)m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).size() - 1;
 			}
-        }, alg );
+        } );
         ifNode.add( line );
         PseudoCodeNode innerIfNode = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if L[i+1][l1] incident to inner segment between L[i+1] and L[i] then", vars ), tree, new IfLoop() {
 			@Override
 			protected boolean condition(Memory m) {
 				return incidentToInnerSegmentBetweenLiPlusOneAndLi( m );
 			}
-		}, alg );
+		} );
         ifNode.add( innerIfNode );
         
         line = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "k1 = pos(pred(L[i+1][l1])[0]);", vars ), tree, new SetVariable<Integer>( "k1" ) {
@@ -174,21 +202,21 @@ public class ConflictDetection implements AlgorithmStage {
 				return (int)m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedLayers().get( m.read( "i", MemoryType.LOCAL ) ).indexOf(
 						m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedLayers().get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 ).get( m.read( "l1", MemoryType.LOCAL ) ).getSortedIncomingEdges().get( 0 ).getSources().get( 0 ) );
 			}
-        }, alg );
+        } );
         innerIfNode.add( line );
         PseudoCodeNode whileLoop = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "while l <= l1 do", vars ), tree, new WhileLoop() {
 			@Override
 			protected boolean condition( Memory m ) {
 				return m.<Integer>read( "l", MemoryType.LOCAL ) <= m.<Integer>read( "l1", MemoryType.LOCAL );
 			}
-        }, alg );
+        } );
         ifNode.add( whileLoop );
         foreach = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "foreach v in pred(L[i+1][l]) do", vars ), tree, new ForEachLoop<LayeredGraphEdge>( "v" ) {
 			@Override
 			protected List<LayeredGraphEdge> list(Memory m) {
 				return m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedLayers().get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 ).get( m.read( "l", MemoryType.LOCAL ) ).getIncomingEdges();
 			}
-        }, alg );
+        } );
         whileLoop.add( foreach );
         innerIfNode = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if pos(v) < k0 or pos(v) > k1 then", vars ), tree, new IfLoop() {
 			@Override
@@ -196,7 +224,7 @@ public class ConflictDetection implements AlgorithmStage {
 			    int k = m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).getContainedLayers().get( m.read( "i", MemoryType.LOCAL ) ).indexOf( m.<LayeredGraphEdge>read( "v", MemoryType.LOCAL ).getSources().get( 0 ) );
 				return k < m.<Integer>read( "k0", MemoryType.LOCAL ) || k > m.<Integer>read( "k1", MemoryType.LOCAL );
 			}
-        }, alg );
+        } );
         foreach.add( innerIfNode );
         line = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "mark segment (v,L[i+1][l]);", vars ), tree, new CodeLine() {
 			@Override
@@ -206,25 +234,24 @@ public class ConflictDetection implements AlgorithmStage {
 				e.setConflicted( true, null );
 				actions.add( (Memory mem) -> {
 					e.setConflicted( old, null );
-					return new ControlFlow( ControlFlow.STEP_OVER );
 				});
 				return new ControlFlow( ControlFlow.STEP_OVER );
 			}
-        }, alg );
+        } );
         innerIfNode.add( line );
         line = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "l = l+1;", vars ), tree, new SetVariable<Integer>( "l" ) {
 			@Override
 			protected Integer value(Memory m) {
 				return (int)m.<Integer>read( "l", MemoryType.LOCAL ) + 1;
 			}
-        }, alg );
+        } );
         whileLoop.add( line );
         line = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "k0 = k1;", vars ), tree, new SetVariable<Integer>( "k0" ) {
 			@Override
 			protected Integer value(Memory m) {
 				return (int)m.<Integer>read( "l1", MemoryType.LOCAL );
 			}
-        }, alg );
+        } );
         ifNode.add( line );
         return root;
     }
@@ -238,40 +265,4 @@ public class ConflictDetection implements AlgorithmStage {
         }
         return false;
     }
-
-    @Override
-    public String getDebugString() {
-        String info = "| i  | l  | l1 | k0 | k1 |  v  |  n  |\n";
-        info +=       "|----|----|----|----|----|-----|-----|\n";
-        String i = "null";
-        String l = "null";
-        String l1 = "null";
-        String k0 = "null";
-        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 ) )
-            l = "" + alg.getMemory().<Integer>read( "l", MemoryType.LOCAL );
-        if( alg.getMemory().isSomewhereDefined( "l1", MemoryType.LOCAL ) )
-            l1 = "" + alg.getMemory().<Integer>read( "l1", MemoryType.LOCAL );
-        if( alg.getMemory().isSomewhereDefined( "k0", MemoryType.LOCAL ) )
-            k0 = "" + alg.getMemory().<Integer>read( "k0", MemoryType.LOCAL );
-        if( alg.getMemory().isSomewhereDefined( "k1", MemoryType.LOCAL ) )
-            k1 = "" + alg.getMemory().<Integer>read( "k1", MemoryType.LOCAL );
-        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();
-        info += "|" + TextLayoutHelper.strToLen( i, 4 ) + 
-                "|" + TextLayoutHelper.strToLen( l, 4 ) + 
-                "|" + TextLayoutHelper.strToLen( l1, 4 ) + 
-                "|" + TextLayoutHelper.strToLen( k0, 4 ) + 
-                "|" + TextLayoutHelper.strToLen( k1, 4 ) + 
-                "|" + TextLayoutHelper.strToLen( v, 5 ) + 
-                "|" + TextLayoutHelper.strToLen( n, 5 ) + "|\n";
-        return info;
-    }
-
 }

+ 1 - 17
src/bk/ExtremalLayoutCalc.java

@@ -3,7 +3,6 @@ package bk;
 import javax.swing.JTree;
 
 import animation.AlgorithmStage;
-import animation.AnimatedAlgorithm;
 import animation.CodeLine;
 import animation.ControlFlow;
 import animation.Memory;
@@ -30,13 +29,6 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
         BOTTOM_TOP_RIGHT,
         COMBINED
     }
-	
-    private AnimatedAlgorithm alg;
-
-    public ExtremalLayoutCalc( AnimatedAlgorithm alg )
-    {
-        this.alg = alg;
-    }
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
@@ -48,15 +40,7 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
 				return null;
 			}
     		
-    	}, alg );
+    	} );
         return root;
     }
-
-    @Override
-    public String getDebugString()
-    {
-        String info = "| Node | Shift | Sink | Root | Align |  x  |  xDef  |\n";
-        info +=       "|------|-------|------|------|-------|-----|--------|\n";
-        return info;
-    }
 }

+ 1 - 6
src/codelines/BackwardForEachLoop.java

@@ -31,9 +31,7 @@ public class BackwardForEachLoop <T> extends CodeLine {
 		if( m.<Integer>read( "line_" + lineId + "_index", MemoryType.LOCAL ) < 0 ) // prove if the loop has finished
 		{
 			m.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-			actions.push( (Memory mem) -> {
-				return new ControlFlow( ControlFlow.STEP_OVER ); // loop was not called so nothing to reverse
-			});
+			actions.push( (Memory mem) -> {});
 			return new ControlFlow( ControlFlow.STEP_OVER ); // don't execute the loop body
 		}
 		if( declared )
@@ -43,7 +41,6 @@ public class BackwardForEachLoop <T> extends CodeLine {
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			} );
 		}
 		else
@@ -60,7 +57,6 @@ public class BackwardForEachLoop <T> extends CodeLine {
 	                m.declare( loopVar, old, MemoryType.LOCAL );
 					mem.write( "line_" + lineId + "_index", oldIndex, MemoryType.LOCAL );
 					mem.addFrame( sf ); // restore last loop stack
-					return new ControlFlow( ControlFlow.STEP_INTO ); // step into the loop body
 				});
 				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			}
@@ -71,7 +67,6 @@ public class BackwardForEachLoop <T> extends CodeLine {
 				mem.removeFrame();
 				mem.addFrame( old );
 				mem.write( "line_" + lineId + "_index", oldIndex, MemoryType.LOCAL );
-				return new ControlFlow( ControlFlow.STEP_INTO );
 			});
 		}
 		return new ControlFlow( ControlFlow.STEP_INTO );

+ 0 - 1
src/codelines/DeclareVariable.java

@@ -26,7 +26,6 @@ public abstract class DeclareVariable <T> extends CodeLine {
 				mem.undeclare( name, MemoryType.LOCAL );
 			else
 				mem.declare( name, oldVal, MemoryType.LOCAL ); // TODO declare in correct stack frame
-			return new ControlFlow( ControlFlow.STEP_OVER );
 		});
 		return new ControlFlow( ControlFlow.STEP_OVER );
 	}

+ 3 - 11
src/codelines/ForEachLoop.java

@@ -29,19 +29,16 @@ public abstract class ForEachLoop <T> extends CodeLine {
 		if( m.<Integer>read( "line_" + lineId + "_index", MemoryType.LOCAL ) > list( m ).size() - 1 ) // prove if the loop has finished
 		{
 			m.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-			actions.push( (Memory mem) -> {
-				return new ControlFlow( ControlFlow.STEP_OVER ); // loop was not called so nothing to reverse
-			});
+			actions.push( (Memory mem) -> {});
 			return new ControlFlow( ControlFlow.STEP_OVER ); // don't execute the loop body
 		}
 		if( declared )
 		{
-			m.declare( loopVar, list( m ).get( m.read( "line_" + lineId + "_index", MemoryType.LOCAL ) ), MemoryType.LOCAL ); // set loop variable
 			m.addFrame( new StackFrame( FrameType.LOOP ) );
+            m.declare( loopVar, list( m ).get( m.read( "line_" + lineId + "_index", MemoryType.LOCAL ) ), MemoryType.LOCAL ); // set loop variable
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			} );
 		}
 		else
@@ -52,24 +49,19 @@ public abstract class ForEachLoop <T> extends CodeLine {
 			{
 				StackFrame sf = m.removeFrame(); // remove loop stack
 				m.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-				T old = m.read( loopVar, MemoryType.LOCAL );
-				m.undeclare( loopVar, MemoryType.LOCAL );
 				actions.push( (Memory mem) -> {
-				    mem.declare( loopVar, old, MemoryType.LOCAL );
 					mem.write( "line_" + lineId + "_index", oldIndex, MemoryType.LOCAL );
 					mem.addFrame( sf ); // restore last loop stack
-					return new ControlFlow( ControlFlow.STEP_INTO ); // step into the loop body
 				});
 				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			}
 			StackFrame old = m.removeFrame(); // fresh stack frame for loop body
 			m.addFrame( new StackFrame( FrameType.LOOP ) );
-			m.write( loopVar, list( m ).get( m.read( "line_" + lineId + "_index", MemoryType.LOCAL ) ), MemoryType.LOCAL ); // update loop variable
+			m.declare( loopVar, list( m ).get( m.read( "line_" + lineId + "_index", MemoryType.LOCAL ) ), MemoryType.LOCAL ); // update loop variable
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.addFrame( old );
 				mem.write( "line_" + lineId + "_index", oldIndex, MemoryType.LOCAL );
-				return new ControlFlow( ControlFlow.STEP_INTO );
 			});
 		}
 		return new ControlFlow( ControlFlow.STEP_INTO );

+ 1 - 6
src/codelines/ForLoop.java

@@ -27,9 +27,7 @@ public abstract class ForLoop extends CodeLine {
 		if( m.<Integer>read( "line_" + lineId + "_index", MemoryType.LOCAL ) > maximum( m ) ) // prove if the loop has finished
 		{
 			m.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-			actions.push( (Memory mem) -> {
-				return new ControlFlow( ControlFlow.STEP_OVER ); // loop was not called so nothing to reverse
-			});
+			actions.push( (Memory mem) -> {});
 			return new ControlFlow( ControlFlow.STEP_OVER ); // don't execute the loop body
 		}
 		if( declared )
@@ -39,7 +37,6 @@ public abstract class ForLoop extends CodeLine {
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.undeclare( "line_" + lineId + "_index", MemoryType.LOCAL );
-				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			} );
 		}
 		else
@@ -56,7 +53,6 @@ public abstract class ForLoop extends CodeLine {
 	                //m.declare( loopVar, old, false );
 					mem.write( "line_" + lineId + "_index", oldIndex, MemoryType.LOCAL );
 					mem.addFrame( sf ); // restore last loop stack
-					return new ControlFlow( ControlFlow.STEP_INTO ); // step into the loop body
 				});
 				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			}
@@ -67,7 +63,6 @@ public abstract class ForLoop extends CodeLine {
 				mem.removeFrame();
 				mem.addFrame( old );
 				mem.write( "line_" + lineId + "_index", oldIndex, MemoryType.LOCAL );
-				return new ControlFlow( ControlFlow.STEP_INTO );
 			});
 		}
 		return new ControlFlow( ControlFlow.STEP_INTO );

+ 0 - 1
src/codelines/FunctionCall.java

@@ -32,7 +32,6 @@ public class FunctionCall extends CodeLine {
 				m.undeclare( "param" + ind, MemoryType.GLOBAL );
 				ind++;
 			}
-			return new ControlFlow( target );
 		} );
 		return new ControlFlow( target );
 	}

+ 1 - 3
src/codelines/FunctionDefinition.java

@@ -18,7 +18,7 @@ public class FunctionDefinition extends CodeLine {
 	
 	@Override
 	public ControlFlow runForward(Memory m) {
-		if( !m.isDefined( "line_" + lineId + "_inside", MemoryType.CURRENT ) )
+		if( !m.isDefined( "line_" + lineId + "_inside", MemoryType.LOCAL ) )
 		{
 			m.addFrame( new StackFrame( FrameType.FUNCTION ) );
 			m.declare( "line_" + lineId + "_inside", true, MemoryType.LOCAL );
@@ -39,7 +39,6 @@ public class FunctionDefinition extends CodeLine {
 					mem.declare( "param" + i, olds[ i - 1], MemoryType.GLOBAL );
 					i++;
 				}
-				return new ControlFlow( ControlFlow.STEP_OVER );
 			} );
 			return new ControlFlow( ControlFlow.STEP_INTO );
 		}
@@ -48,7 +47,6 @@ public class FunctionDefinition extends CodeLine {
 			StackFrame frame = m.removeFrame();
 			actions.push( (Memory mem) -> {
 				mem.addFrame( frame );
-				return new ControlFlow( ControlFlow.STEP_INTO ); // call function backwards
 			} );
 			return new ControlFlow( ControlFlow.STEP_OVER ); // return
 		}

+ 2 - 6
src/codelines/IfLoop.java

@@ -16,12 +16,11 @@ public abstract class IfLoop extends CodeLine {
 
 	@Override
 	public ControlFlow runForward(Memory m) {
-		if( m.isDefined( "line_" + lineId + "_inside", MemoryType.CURRENT ) )
+		if( m.isDefined( "line_" + lineId + "_inside", MemoryType.LOCAL ) )
 		{
 			StackFrame old = m.removeFrame();
 			actions.push( (Memory mem) -> {
 				mem.addFrame( old );
-            	return new ControlFlow( ControlFlow.STEP_INTO );
 			} );
             return new ControlFlow( ControlFlow.STEP_OVER );
 		}
@@ -32,13 +31,10 @@ public abstract class IfLoop extends CodeLine {
             	m.declare( "line_" + lineId + "_inside", true, MemoryType.LOCAL );
             	actions.push( (Memory mem) -> {
             		mem.removeFrame();
-            		return new ControlFlow( ControlFlow.STEP_OVER );
             	} );
             	return new ControlFlow( ControlFlow.STEP_INTO );
             } else {
-            	actions.push( (Memory mem) -> {
-	                return new ControlFlow( ControlFlow.STEP_OVER );
-            	} );
+            	actions.push( (Memory mem) -> {} );
                 return new ControlFlow( ControlFlow.STEP_OVER );
             }
 		}

+ 0 - 1
src/codelines/SetVariable.java

@@ -26,7 +26,6 @@ public abstract class SetVariable <T> extends CodeLine {
                 mem.undeclare( name, MemoryType.LOCAL );
             else
                 mem.write( name, oldVal, MemoryType.LOCAL ); // TODO write in correct stack frame
-            return new ControlFlow( ControlFlow.STEP_OVER );
         });
         return new ControlFlow( ControlFlow.STEP_OVER );
     }

+ 1 - 6
src/codelines/WhileLoop.java

@@ -23,14 +23,11 @@ public abstract class WhileLoop extends CodeLine {
                 StackFrame sf = m.removeFrame(); // remove loop stack
                 actions.push( (Memory mem) -> {
                     mem.addFrame( sf ); // restore last loop stack
-                    return new ControlFlow( ControlFlow.STEP_INTO ); // step into the loop body
                 });
             }
             else
             {
-                actions.push( (Memory mem) -> {
-                    return new ControlFlow( ControlFlow.STEP_INTO ); // step into the loop body
-                });
+                actions.push( (Memory mem) -> {});
             }
             return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
         }
@@ -40,7 +37,6 @@ public abstract class WhileLoop extends CodeLine {
             m.declare( "line_" + lineId + "_index", 0, MemoryType.LOCAL );
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
-				return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
 			} );
 		}
 		else
@@ -51,7 +47,6 @@ public abstract class WhileLoop extends CodeLine {
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.addFrame( old );
-				return new ControlFlow( ControlFlow.STEP_INTO );
 			});
 		}
 		return new ControlFlow( ControlFlow.STEP_INTO );