WhileLoop.java 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package codelines;
  2. import animation.CodeLine;
  3. import animation.ControlFlow;
  4. import animation.Memory;
  5. import animation.StackFrame;
  6. import animation.StackFrame.FrameType;
  7. public abstract class WhileLoop extends CodeLine {
  8. @Override
  9. public ControlFlow runForward(Memory m) {
  10. boolean declared = false; // prove if it is the first step in the loop
  11. if( !m.isSomewhereDefined( "line_" + lineId + "_index", false ) )
  12. { // first loop step
  13. m.declare( "line_" + lineId + "_index", 0, false );
  14. declared = true;
  15. }
  16. if( !condition( m ) ) // prove if the loop has finished
  17. {
  18. m.undeclare( "line_" + lineId + "_index", false );
  19. actions.push( (Memory mem) -> {
  20. return new ControlFlow( ControlFlow.STEP_OVER ); // loop was not called so nothing to reverse
  21. });
  22. return new ControlFlow( ControlFlow.STEP_OVER ); // don't execute the loop body
  23. }
  24. if( declared )
  25. {
  26. m.addFrame( new StackFrame( FrameType.LOOP ) );
  27. actions.push( (Memory mem) -> {
  28. mem.removeFrame();
  29. mem.undeclare( "line_" + lineId + "_index", false );
  30. return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
  31. } );
  32. }
  33. else
  34. {
  35. if( !condition( m ) ) // prove if loop was finished
  36. {
  37. StackFrame sf = m.removeFrame(); // remove loop stack
  38. m.undeclare( "line_" + lineId + "_index", false );
  39. actions.push( (Memory mem) -> {
  40. mem.declare( "line_" + lineId + "_index", 0, false );
  41. mem.addFrame( sf ); // restore last loop stack
  42. return new ControlFlow( ControlFlow.STEP_INTO ); // step into the loop body
  43. });
  44. return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
  45. }
  46. StackFrame old = m.removeFrame(); // fresh stack frame for loop body
  47. m.addFrame( new StackFrame( FrameType.LOOP ) );
  48. actions.push( (Memory mem) -> {
  49. mem.removeFrame();
  50. mem.addFrame( old );
  51. return new ControlFlow( ControlFlow.STEP_INTO );
  52. });
  53. }
  54. return new ControlFlow( ControlFlow.STEP_INTO );
  55. }
  56. abstract protected boolean condition( Memory m );
  57. }