package codeline;

import java.util.Stack;

import processor.ControlFlow;
import processor.Memory;

/**
 * A line of pseudo code that can be executed.
 * @author kolja
 *
 */
public abstract class CodeLine {
    /**
     * an action that undoes what the {@link CodeLine} did
     * @author kolja
     *
     */
	public interface BackwardAction
	{
		public void backward( Memory m );
	}
	
	protected Stack<BackwardAction> actions;
	protected int lineId;
	private static int nextLineId = 0;
	
	/**
	 * creates a new line of code
	 */
	public CodeLine()
	{
		synchronized( CodeLine.class ) {
			lineId = nextLineId++;
		}
		actions = new Stack<BackwardAction>();
	}
	
	/**
	 * executes the line of code
	 * @param m the memory in which the variables are
	 * @return what should be executed next
	 */
    public abstract ControlFlow runForward( Memory m );
    
    /**
     * undo a call of {@code runForward}
     * @param m the memory in which the variables are
     */
    public void runBackward( Memory m )
    {
    	if( actions.size() != 0 )
    	    actions.pop().backward( m );
    }

    /**
     * creates an empty backwards action and pushes it to the stack
     */
    public void createEmptyBackwardsAction() {
        actions.push( (Memory mem) -> {} ); // add empty reverse function
    }
}
