package codeline;

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

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, Visibility.LOCAL );
        T oldVal = m.read( name, Visibility.LOCAL );
        m.write( name, value( m.createReadOnlyMemory() ), Visibility.LOCAL );
        actions.push( (Memory mem) -> {
            if( !oldExists )
                mem.undeclare( name, Visibility.LOCAL );
            else
                mem.write( name, oldVal, Visibility.LOCAL );
        });
        return new ControlFlow( ControlFlow.STEP_OVER );
    }
    
    abstract protected T value( ReadOnlyMemory m );
}
