AbstractForLoop.java 2.3 KB

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