package codelines;

import animation.CodeLine;
import animation.ControlFlow;
import animation.Memory;
import animation.Memory.MemoryType;
import animation.Memory.ReadOnlyMemory;

public abstract class SetVariable <T> extends CodeLine {

    private boolean oldExists;
    private String name;
    
    public SetVariable( String name )
    {
        this.name = name;
    }

    @Override
    public ControlFlow runForward(Memory m) {
        
        oldExists = m.isDefined( name, MemoryType.LOCAL );
        T oldVal = m.read( name, MemoryType.LOCAL );
        m.write( name, value( m.createReadOnlyMemory() ), MemoryType.LOCAL );
        actions.push( (Memory mem) -> {
            if( !oldExists )
                mem.undeclare( name, MemoryType.LOCAL );
            else
                mem.write( name, oldVal, MemoryType.LOCAL ); // TODO write in correct stack frame
        });
        return new ControlFlow( ControlFlow.STEP_OVER );
    }
    
    abstract protected T value( ReadOnlyMemory m );
}
