|
@@ -42,7 +42,7 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
private boolean renderImage = true;
|
|
|
private JFrame view;
|
|
|
private ProcessController controller;
|
|
|
- private boolean insideNotSkipLoop = false;
|
|
|
+ private boolean insideNotSkipLoop = false;
|
|
|
|
|
|
|
|
|
* creates a new {@link PseudoCodeProcessor}
|
|
@@ -65,30 +65,57 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
|
|
|
public ProcessController getController()
|
|
|
{
|
|
|
- return controller;
|
|
|
+ return controller;
|
|
|
}
|
|
|
|
|
|
private CodeStatus selectNextNode( PseudoCodeNode next, PseudoCodeNode last )
|
|
|
{
|
|
|
programPointer = next;
|
|
|
last.setSelected( false );
|
|
|
- switch( next.setSelected( true ) )
|
|
|
- {
|
|
|
+ switch( next.setSelected( true ) )
|
|
|
+ {
|
|
|
case CONTINUE:
|
|
|
+
|
|
|
skip = false;
|
|
|
return CodeStatus.UNFINISHED;
|
|
|
case SKIP:
|
|
|
+
|
|
|
skip = true;
|
|
|
if( insideNotSkipLoop )
|
|
|
return CodeStatus.UNFINISHED;
|
|
|
return forwardStepOverUntilNotSkip();
|
|
|
case STOP:
|
|
|
+
|
|
|
skip = false;
|
|
|
return CodeStatus.BREAKPOINT;
|
|
|
default:
|
|
|
- break;
|
|
|
+ return CodeStatus.UNFINISHED;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private CodeStatus selectBeforeNode( PseudoCodeNode next, PseudoCodeNode last )
|
|
|
+ {
|
|
|
+ programPointer = next;
|
|
|
+ last.setSelected( false );
|
|
|
+ switch( next.setSelected( true ) )
|
|
|
+ {
|
|
|
+ case CONTINUE:
|
|
|
+
|
|
|
+ skip = false;
|
|
|
+ return CodeStatus.UNFINISHED;
|
|
|
+ case SKIP:
|
|
|
+
|
|
|
+ skip = true;
|
|
|
+ if( insideNotSkipLoop )
|
|
|
+ return CodeStatus.UNFINISHED;
|
|
|
+ return backwardStepOverUntilNotSkip();
|
|
|
+ case STOP:
|
|
|
+
|
|
|
+ skip = false;
|
|
|
+ return CodeStatus.BREAKPOINT;
|
|
|
+ default:
|
|
|
+ return CodeStatus.UNFINISHED;
|
|
|
}
|
|
|
- return CodeStatus.UNFINISHED;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -97,11 +124,16 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
*/
|
|
|
protected CodeStatus forwardStep()
|
|
|
{
|
|
|
+
|
|
|
if( programPointer == null )
|
|
|
return CodeStatus.FINISHED;
|
|
|
+
|
|
|
+
|
|
|
StackFrame before = mem.removeFrame();
|
|
|
mem.addFrame( before );
|
|
|
ControlFlow cf = null;
|
|
|
+
|
|
|
+
|
|
|
if( mem.isDefined( "_call" + programPointer.getId(), Visibility.LOCAL ) )
|
|
|
{
|
|
|
String name = "_call" + programPointer.getId();
|
|
@@ -113,11 +145,16 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
}
|
|
|
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(), Visibility.GLOBAL ) )
|
|
|
{
|
|
|
String name = "_returnTo" + programPointer.getId();
|
|
@@ -132,9 +169,10 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
throw new IllegalStateException( "A Codeline without sublines tried to make a STEP_INTO." );
|
|
|
else
|
|
|
return selectNextNode( (PseudoCodeNode)programPointer.getFirstChild(), programPointer );
|
|
|
- case ControlFlow.STEP_OVER:
|
|
|
+ case ControlFlow.STEP_OVER:
|
|
|
if( programPointer.getParent() == null )
|
|
|
return CodeStatus.FINISHED;
|
|
|
+
|
|
|
if( before.isDefined( "_returnTo" + programPointer.getId() ) )
|
|
|
{
|
|
|
String name = "_returnTo" + programPointer.getId();
|
|
@@ -143,15 +181,18 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
cf.setBackwardAction( (Memory m) -> {
|
|
|
before.declare( name, 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:
|
|
|
+ case ControlFlow.CALL:
|
|
|
PseudoCodeNode f = cf.getFunction();
|
|
|
+
|
|
|
String name = "_call" + programPointer.getId();
|
|
|
mem.declare( name, true, Visibility.LOCAL );
|
|
|
mem.declare( "_returnTo" + f.getId(), cf.getJumpBack(), Visibility.GLOBAL );
|
|
@@ -159,17 +200,19 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
m.undeclare( "_returnTo" + f.getId(), Visibility.GLOBAL );
|
|
|
m.undeclare( name, Visibility.LOCAL );
|
|
|
});
|
|
|
+
|
|
|
return selectNextNode( f, programPointer );
|
|
|
default:
|
|
|
- break;
|
|
|
+ throw new IllegalStateException( "Unknown ControlFlow action" );
|
|
|
}
|
|
|
- throw new IllegalStateException( "Unknown ControlFlow action" );
|
|
|
}
|
|
|
|
|
|
private CodeStatus forwardStepOverUntilNotSkip() {
|
|
|
+
|
|
|
if( programPointer == null )
|
|
|
return CodeStatus.FINISHED;
|
|
|
CodeStatus status = CodeStatus.UNFINISHED;
|
|
|
+
|
|
|
do {
|
|
|
insideNotSkipLoop = true;
|
|
|
status = forwardStep();
|
|
@@ -180,10 +223,13 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
|
|
|
protected 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 );
|
|
@@ -192,39 +238,23 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
|
|
|
protected 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:
|
|
|
- skip = false;
|
|
|
- return CodeStatus.UNFINISHED;
|
|
|
- case SKIP:
|
|
|
- skip = true;
|
|
|
- if( insideNotSkipLoop )
|
|
|
- return CodeStatus.UNFINISHED;
|
|
|
- return backwardStepOverUntilNotSkip();
|
|
|
- case STOP:
|
|
|
- skip = false;
|
|
|
- return CodeStatus.BREAKPOINT;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- return CodeStatus.UNFINISHED;
|
|
|
- }
|
|
|
-
|
|
|
+
|
|
|
+ * returns the program pointer of the previous step
|
|
|
+ * @return the node that was previously executed
|
|
|
+ */
|
|
|
protected PseudoCodeNode getLastProgramPointer() {
|
|
|
if( controlStack.isEmpty() )
|
|
|
return null;
|
|
@@ -233,21 +263,28 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
|
|
|
protected CodeStatus backwardStep()
|
|
|
{
|
|
|
+
|
|
|
if( 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 );
|
|
|
}
|
|
|
|
|
|
private CodeStatus backwardStepOverUntilNotSkip()
|
|
|
{
|
|
|
+
|
|
|
if( programPointer == null )
|
|
|
return CodeStatus.FINISHED;
|
|
|
CodeStatus status = CodeStatus.UNFINISHED;
|
|
|
+
|
|
|
do {
|
|
|
insideNotSkipLoop = true;
|
|
|
status = backwardStep();
|
|
@@ -258,10 +295,13 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
|
|
|
protected 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 );
|
|
@@ -270,10 +310,13 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
|
|
|
protected 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 );
|
|
@@ -305,14 +348,14 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
{
|
|
|
while( true )
|
|
|
{
|
|
|
- CodeStatus status = null;
|
|
|
+ CodeStatus status = null;
|
|
|
try {
|
|
|
- Action action = controller.getNextAction();
|
|
|
- graph.unselectGraph();
|
|
|
- switch( action )
|
|
|
+ Action action = controller.getNextAction();
|
|
|
+ graph.unselectGraph();
|
|
|
+ switch( action )
|
|
|
{
|
|
|
case FORWARD:
|
|
|
- status = forwardStep();
|
|
|
+ status = forwardStep();
|
|
|
break;
|
|
|
case FORWARD_OUT:
|
|
|
status = forwardStepOut();
|
|
@@ -341,11 +384,14 @@ public class PseudoCodeProcessor extends Thread {
|
|
|
e.printStackTrace();
|
|
|
return;
|
|
|
}
|
|
|
- update();
|
|
|
- if( status == CodeStatus.FINISHED )
|
|
|
+
|
|
|
+
|
|
|
+ update();
|
|
|
+
|
|
|
+ if( status == CodeStatus.FINISHED )
|
|
|
{
|
|
|
- controller.setContinuous( false );
|
|
|
- controller.setNextAction( null );
|
|
|
+ controller.setContinuous( false );
|
|
|
+ controller.setNextAction( null );
|
|
|
}
|
|
|
}
|
|
|
}
|