package ga050426;

class RelocEntries {
	int loc;
	int seg;
	int ref;
	String symref = null;
	String type = null;
	RelocEntries prev = null, next = null;

	public RelocEntries(int loc, int seg, int ref, String simref,
			String type, RelocEntries prev, RelocEntries next) {
		this.loc = loc;
		this.seg = seg;
		this.ref = ref;
		this.symref = simref;
		this.type = type;
		this.prev = prev;
		this.next = next;
	}
}

public class Relocations {
	private RelocEntries head = null, tail = null;
	public static Relocations instance = new Relocations();
	public int rels = 0;

	public void enter(int loc, int seg, String simref, String mnemonic) 
	throws SymbolLeavedUndefinedException{
		String type = "";
		if( Opcodes.getOpcode(mnemonic) == Opcodes.BRR ||
			Opcodes.getOpcode(mnemonic) == Opcodes.BZE ||
			Opcodes.getOpcode(mnemonic) == Opcodes.BNZ ||
			Opcodes.getOpcode(mnemonic) == Opcodes.BPZ ||
			Opcodes.getOpcode(mnemonic) == Opcodes.BNG ||
			Opcodes.getOpcode(mnemonic) == Opcodes.BCC ||
			Opcodes.getOpcode(mnemonic) == Opcodes.BCS ||
			Opcodes.getOpcode(mnemonic) == Opcodes.JSR ||
			Opcodes.getOpcode(mnemonic) == Opcodes.ORA ||
			Opcodes.getOpcode(mnemonic) == Opcodes.ANA ||
			Opcodes.getOpcode(mnemonic) == Opcodes.CMP ||
			Opcodes.getOpcode(mnemonic) == Opcodes.SBC ||
			Opcodes.getOpcode(mnemonic) == Opcodes.SUB ||
			Opcodes.getOpcode(mnemonic) == Opcodes.ADC ||
			Opcodes.getOpcode(mnemonic) == Opcodes.ADD ||
			Opcodes.getOpcode(mnemonic) == Opcodes.LDR
		)
			type = "R";
		else type = "A";
		
		int ref = 0;
		if(!simref.equals("")){
			STEntries sim = Symbols.instance.getValueOf(simref);
			if(sim.globuse){
				type+="S";
				ref=sim.number;
			}
			else
			ref=sim.segment;
		}
		type+="1";	
		if (tail != null){
			tail = tail.next = new RelocEntries(loc, seg, ref, simref,
					type, tail, null);
		}
		else
			tail = head = new RelocEntries(loc, seg,ref, simref, type,
					tail, null);
		rels++;
	}
	
	public String toString() {
		StringBuffer buf = new StringBuffer(String
				.format("#Relocations (hex)%n"));
		for (RelocEntries cur = head; cur != null; cur = cur.next) {
			buf.append(String.format(" %x\t%x\t%x\t%-3s%n", cur.loc, cur.seg,
					cur.ref, cur.type));
		}
		return new String(buf);
	}
}
