浏览代码

forwärtz funktioniert fast, aber is gibt eine merkrürdige schleife in der sich der komplette algorithmus wiederhohlt

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

+ 10 - 0
src/animation/AnimatedAlgorithm.java

@@ -9,6 +9,7 @@ import javax.swing.JTree;
 import javax.swing.SwingUtilities;
 
 import animation.PseudoCodeNode.CodeStatus;
+import animation.StackFrame.FrameType;
 import graph.LayeredGraphNode;
 
 public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage {
@@ -19,6 +20,7 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
     protected PseudoCodeNode root;
     protected Stack<PseudoCodeNode> activeFunction;
     protected Memory mem;
+    private Memory fstack;
 
     public AnimatedAlgorithm( AnimationController controller, LayeredGraphNode graph, JFrame view )
     {
@@ -29,10 +31,14 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
         mem = new Memory();
         mem.declare( "graph", graph, true );
         activeFunction = new Stack<PseudoCodeNode>();
+        fstack = new Memory();
     }
     
     public void addActiveFunction( PseudoCodeNode n )
     {
+    	if( !activeFunction.empty() )
+    		activeFunction.peek().writeToStack( fstack );
+        fstack.addFrame( new StackFrame( FrameType.FUNCTION ) );
     	activeFunction.push( n );
     }
 
@@ -88,7 +94,11 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
             if( status == CodeStatus.FINISHED )
             {
             	if( activeFunction.size() > 1 )
+            	{
+            		fstack.removeFrame();
             		activeFunction.pop();
+            		activeFunction.peek().loadFromStack( fstack );
+            	}
             }
         }
     }

+ 3 - 2
src/animation/Memory.java

@@ -75,17 +75,18 @@ public class Memory {
         }
     }
     
-    public boolean isSomewhereDefined( String name, boolean global )
+    public boolean isSomewhereDefined( String name, boolean global, int maxDepth )
     {
     	if( global )
     		return this.global.isDefined( name );
     	int index = stack.size() - 1;
-    	while( index >= 0 ) {
+    	while( index >= 0 && maxDepth >= 0 ) {
     	   StackFrame stackF = stack.get( index-- );
     	   if( stackF.isDefined( name ) )
     		   return true;
     	   if( stackF.getType() == FrameType.FUNCTION )
     		   break;
+    	   maxDepth--;
     	}
     	return false;
     }

+ 13 - 16
src/animation/PseudoCodeNode.java

@@ -5,6 +5,8 @@ import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.MutableTreeNode;
 import javax.swing.tree.TreePath;
 
+import animation.StackFrame.FrameType;
+
 /**
  * represents a line of pseudocode
  * @author kolja
@@ -68,7 +70,7 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
         controller = c;
     }
     
-    private void writeToStack( Memory m )
+    public void writeToStack( Memory m )
     {
     	if( m.isDefined( "_pos" + nodeId, false ) )
     		throw new IllegalStateException( "variable _pos" + nodeId + " should not exist in current stack frame, but it exists" );
@@ -76,6 +78,8 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
     		throw new IllegalStateException( "variable _func" + nodeId + " should not exist in current stack frame, but it exists" );
     	m.declare( "_pos" + nodeId, currentCodeLine, false );
     	m.declare( "_func" + nodeId, function, false );
+    	currentCodeLine = -1;
+    	function = false;
     	setSelected( false );
     	if( children == null )
     		return;
@@ -83,7 +87,7 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
     		((PseudoCodeNode)c).writeToStack( m );
     }
     
-    private void loadFromStack( Memory m )
+    public void loadFromStack( Memory m )
     {
     	if( !m.isDefined( "_pos" + nodeId, false ) )
     		throw new IllegalStateException( "variable _pos" + nodeId + "should exist in current stack frame, but it is undefined" );
@@ -236,23 +240,20 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
     {
         if( currentCodeLine == -1 )
         {
-			if( !m.isDefined( "line_" + nodeId + "_call", false ) )
+			if( !m.isDefined( "node_" + nodeId + "_call", false ) )
 			{
 				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 );
+				}
+				ControlFlow cf = code.runForward( m );
 	            switch( cf.getStatus() )
 	            {
 	            case ControlFlow.STEP_INTO:
+	            	writeToStack( m );
 	            	function = true;
-	            	if( children != null )
-	            	{
-	            		for( Object c : children )
-	            			((PseudoCodeNode)c).writeToStack( m );
-	            	}
 	                switch( stepInto( m ) )
 	                {
 					case BREAKPOINT:
@@ -275,17 +276,13 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
 	            	if( function )
 	            	{
 	            		m.addFrame( tmp ); // add old stack frame
-	                	if( children != null )
-	                	{
-	                		for( Object c : children )
-	                			((PseudoCodeNode)c).loadFromStack( m ); // load stored variables
-	                	}
+		            	loadFromStack( m ); // load stored variables
 	                	m.removeFrame(); // remove the stack frame
 	            	}
 	                return CodeStatus.FINISHED;
 	            case ControlFlow.CALL:
 	    			alg.addActiveFunction( cf.getFunction() );
-	    			m.declare( "line_" + nodeId + "_call", true, false );
+	    			m.declare( "node_" + nodeId + "_call", cf.getFunction(), false );
 	    			setSelected( false );
 	    			m.declare( "callback", this, true );
 	    			switch( cf.getFunction().setSelected( true ) )
@@ -311,7 +308,7 @@ public class PseudoCodeNode extends DefaultMutableTreeNode {
 			}
 			else
 			{
-				m.undeclare( "line_" + nodeId + "_call", false );
+				m.undeclare( "node_" + nodeId + "_call", false );
 				return CodeStatus.FINISHED;
 			}
         }

+ 2 - 2
src/codelines/BackwardForEachLoop.java

@@ -22,7 +22,7 @@ public class BackwardForEachLoop <T> extends CodeLine {
 	@Override
 	public ControlFlow runForward(Memory m) {
 		boolean declared = false; // prove if it is the first step in the loop
-		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false ) )
+		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false, 1 ) )
 		{ // first loop step
 			m.declare( "line_" + lineId + "_index", m.<List<T>>read( listVar, false ).size() - 1, false );
 			declared = true;
@@ -37,8 +37,8 @@ public class BackwardForEachLoop <T> extends CodeLine {
 		}
 		if( declared )
 		{
-			m.addFrame( new StackFrame( FrameType.LOOP ) );
 			m.declare( loopVar, m.<List<T>>read( listVar, false ).get( m.read( "line_" + lineId + "_index", false ) ), false ); // set loop variable
+			m.addFrame( new StackFrame( FrameType.LOOP ) );
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.undeclare( "line_" + lineId + "_index", false );

+ 2 - 2
src/codelines/ForEachLoop.java

@@ -20,7 +20,7 @@ public abstract class ForEachLoop <T> extends CodeLine {
 	@Override
 	public ControlFlow runForward(Memory m) {
 		boolean declared = false; // prove if it is the first step in the loop
-		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false ) )
+		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false, 1 ) )
 		{ // first loop step
 			m.declare( "line_" + lineId + "_index", 0, false );
 			declared = true;
@@ -35,8 +35,8 @@ public abstract class ForEachLoop <T> extends CodeLine {
 		}
 		if( declared )
 		{
-			m.addFrame( new StackFrame( FrameType.LOOP ) );
 			m.declare( loopVar, list( m ).get( m.read( "line_" + lineId + "_index", false ) ), false ); // set loop variable
+			m.addFrame( new StackFrame( FrameType.LOOP ) );
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.undeclare( "line_" + lineId + "_index", false );

+ 2 - 2
src/codelines/ForLoop.java

@@ -18,7 +18,7 @@ public abstract class ForLoop extends CodeLine {
 	@Override
 	public ControlFlow runForward(Memory m) {
 		boolean declared = false; // prove if it is the first step in the loop
-		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false ) )
+		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false, 1 ) )
 		{ // first loop step
 			m.declare( "line_" + lineId + "_index", minimum( m ), false );
 			declared = true;
@@ -33,8 +33,8 @@ public abstract class ForLoop extends CodeLine {
 		}
 		if( declared )
 		{
-			m.addFrame( new StackFrame( FrameType.LOOP ) );
 			m.declare( loopVar, minimum( m ), false ); // set loop variable
+			m.addFrame( new StackFrame( FrameType.LOOP ) );
 			actions.push( (Memory mem) -> {
 				mem.removeFrame();
 				mem.undeclare( "line_" + lineId + "_index", false );

+ 1 - 1
src/codelines/WhileLoop.java

@@ -11,7 +11,7 @@ public abstract class WhileLoop extends CodeLine {
 	@Override
 	public ControlFlow runForward(Memory m) {
 		boolean declared = false; // prove if it is the first step in the loop
-		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false ) )
+		if( !m.isSomewhereDefined( "line_" + lineId + "_index", false, 1 ) )
 		{ // first loop step
 			m.declare( "line_" + lineId + "_index", 0, false );
 			declared = true;