|
@@ -1,5 +1,7 @@
|
|
|
package animation;
|
|
|
|
|
|
+import java.util.Stack;
|
|
|
+
|
|
|
import animation.Memory.MemoryType;
|
|
|
import animation.StackFrame.FrameType;
|
|
|
|
|
@@ -15,6 +17,7 @@ public class PseudoCodeProcessor {
|
|
|
private String currentDebugOutput;
|
|
|
private Memory mem;
|
|
|
private PseudoCodeNode programPointer;
|
|
|
+ private Stack<ControlFlow> controlStack;
|
|
|
|
|
|
public PseudoCodeProcessor( PseudoCodeNode tree )
|
|
|
{
|
|
@@ -22,6 +25,7 @@ public class PseudoCodeProcessor {
|
|
|
mem.addFrame( new StackFrame( FrameType.FUNCTION ) );
|
|
|
programPointer = tree;
|
|
|
currentDebugOutput = "";
|
|
|
+ controlStack = new Stack<>();
|
|
|
}
|
|
|
|
|
|
private CodeStatus selectNextNode( PseudoCodeNode next, PseudoCodeNode last )
|
|
@@ -46,15 +50,30 @@ public class PseudoCodeProcessor {
|
|
|
return CodeStatus.FINISHED;
|
|
|
StackFrame before = mem.removeFrame();
|
|
|
mem.addFrame( before );
|
|
|
- ControlFlow cf = programPointer.forwardStep( mem );
|
|
|
+ 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, mem.read( "_returnTo" + programPointer.getId(), MemoryType.GLOBAL ), MemoryType.LOCAL );
|
|
|
+ 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." );
|
|
@@ -67,6 +86,9 @@ public class PseudoCodeProcessor {
|
|
|
{
|
|
|
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 );
|
|
@@ -75,8 +97,14 @@ public class PseudoCodeProcessor {
|
|
|
else
|
|
|
return selectNextNode( nextPC, programPointer );
|
|
|
case ControlFlow.CALL:
|
|
|
- mem.declare( "_returnTo" + cf.getFunction().getId(), programPointer, MemoryType.GLOBAL );
|
|
|
- return selectNextNode( cf.getFunction(), programPointer );
|
|
|
+ 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" );
|
|
|
}
|
|
@@ -123,43 +151,14 @@ public class PseudoCodeProcessor {
|
|
|
|
|
|
public CodeStatus backwardStep()
|
|
|
{
|
|
|
- if( programPointer == null )
|
|
|
+ if( programPointer == null || controlStack.isEmpty() )
|
|
|
return CodeStatus.FINISHED;
|
|
|
- StackFrame before = mem.removeFrame();
|
|
|
- mem.addFrame( before );
|
|
|
- ControlFlow cf = programPointer.backwardStep( mem );
|
|
|
- currentDebugOutput = programPointer.getDebugOutput( 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" );
|
|
|
+ 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()
|