/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template 
 varsin the editor.
 */
package targets.mips;

import java.util.LinkedList;

/**
 *
 * @author Eugenio
 */
public class Registers {

    protected int arg = 0;

    public String Arg() {
        return "a" + (arg++);
    }

    public void ResetArgs() {
        arg = 0;
    }

    protected final LinkedList<String> avaliableSaved = new LinkedList<String>() {
        {
            for (int i = 0; i < 8; i++) {
                add("s" + i);
            }
        }
    };
    protected final LinkedList<String> avaliableTemp = new LinkedList<String>() {
        {
            for (int i = 0; i < 9; i++) {
                add("t" + i);
            }
        }
    };
    protected final LinkedList<String> usedSaved = new LinkedList<>();
    protected final LinkedList<String> usedTemp = new LinkedList<>();

    public Registers() {

    }

    public boolean Free(String reg) throws Exception {
        return exec(reg, "free") != null;
    }

    public String Lock(String reg) throws Exception {
        return exec(reg, "lock");
    }

    private String exec(String reg, String act) throws Exception {
//        System.out.println("Exec:" + reg + ":" + act);
        LinkedList<String> u, a;
        String r = null;
        switch (reg.substring(0, 1)) {
            case "t":
                u = usedTemp;
                a = avaliableTemp;
                break;
            case "s":
                u = usedSaved;
                a = avaliableSaved;
                break;
            default:
                throw new Exception("Try " + act + " register '%s'");
        }
        switch (act) {
            case "free":
                if (!u.isEmpty()) {
//                    System.out.println("Try remove(" + reg + ") from " + u);
                    // Encontra o registrador usado e coloca como disponivel
                    int index = u.indexOf(reg);
                    if (index >= 0) {
                        r = u.remove(index);
                        a.add(r);
                    }
                }
                break;
            case "lock":
                if (!a.isEmpty()) {
                    // Pega o primeiro registrador disponivel e marca como usado
                    r = a.removeFirst();
                    u.add(r);
                }
                break;
        }
        return r;
    }
}
