package codeline;

import processor.ControlFlow;
import processor.Memory;
import processor.StackFrame;
import processor.Memory.ReadOnlyMemory;
import processor.Memory.Visibility;
import processor.StackFrame.FrameType;

/**
 * Yey, IF is a LOOP.
 * @author kolja
 *
 */
public abstract class IfLoop extends CodeLine {

	@Override
	public ControlFlow runForward(Memory m) {
		if( m.isDefined( "line_" + lineId + "_inside", Visibility.LOCAL ) )
		{
			StackFrame old = m.removeFrame();
			actions.push( (Memory mem) -> {
				mem.addFrame( old );
			} );
            return new ControlFlow( ControlFlow.STEP_OVER );
		}
		else
		{
            if( condition( m.createReadOnlyMemory() ) ) {
            	m.addFrame( new StackFrame( FrameType.LOOP ) );
            	m.declare( "line_" + lineId + "_inside", true, Visibility.LOCAL );
            	actions.push( (Memory mem) -> {
            		mem.removeFrame();
            	} );
            	return new ControlFlow( ControlFlow.STEP_INTO );
            } else {
            	actions.push( (Memory mem) -> {} );
                return new ControlFlow( ControlFlow.STEP_OVER );
            }
		}
	}

	abstract protected boolean condition( ReadOnlyMemory m );
}
