AbstractForLoop.java 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package codelines;
  2. import animation.CodeLine;
  3. import animation.ControlFlow;
  4. import animation.Memory;
  5. import animation.StackFrame;
  6. import animation.Memory.MemoryType;
  7. import animation.StackFrame.FrameType;
  8. public abstract class AbstractForLoop<T> extends CodeLine {
  9. String loopVar;
  10. public AbstractForLoop( String varName )
  11. {
  12. this.loopVar = varName;
  13. }
  14. @Override
  15. public ControlFlow runForward(Memory m) {
  16. if( !m.isDefined( loopVar, MemoryType.LOCAL ) )
  17. { // first loop step
  18. m.addFrame( new StackFrame( FrameType.LOOP ) );
  19. m.declare( loopVar, begin( m ), MemoryType.LOCAL ); // set loop variable
  20. if( !condition( m ) ) // prove if the loop has finished
  21. {
  22. m.removeFrame();
  23. actions.push( (Memory mem) -> {} );
  24. return new ControlFlow( ControlFlow.STEP_OVER ); // don't execute the loop body
  25. }
  26. actions.push( (Memory mem) -> {
  27. mem.removeFrame();
  28. } );
  29. }
  30. BackwardAction reverseChange = change( m );
  31. if( !condition( m ) ) // prove if loop was finished
  32. {
  33. StackFrame sf = m.removeFrame(); // remove loop stack
  34. actions.add( (Memory mem) -> {
  35. mem.addFrame( sf ); // restore last loop stack
  36. reverseChange.backward( mem );
  37. });
  38. return new ControlFlow( ControlFlow.STEP_OVER ); // step out of the loop
  39. }
  40. StackFrame old = m.removeFrame(); // fresh stack frame for loop body
  41. m.addFrame( new StackFrame( FrameType.LOOP ) );
  42. actions.push( (Memory mem) -> {
  43. mem.removeFrame();
  44. mem.addFrame( old );
  45. });
  46. return new ControlFlow( ControlFlow.STEP_INTO );
  47. }
  48. abstract protected T begin( Memory m );
  49. abstract protected BackwardAction change( Memory m );
  50. abstract protected boolean condition( Memory m );
  51. }