/* SymbolT.java - zapouzdruje tabulku symbolu.
 *
 * Michal Beran, berny@students.zcu.cz
 * 4.1.2001
 */
package pl0prog;

import java.io.*;


/** Trida SymbolT implementuje tabulku symbolu pouzivanou prekladacem a interpretem
  * jazyka PL/0.
  */
public class SymbolT{
	/** Maximalni pocet identifikatoru v tabulce */
	final int TXMAX = 5000; 
	/** Nejvyssi mozna adesa */
	final int AMAX = 2048;  
	/** Tabulka identifikatoru */
	Identifier[] Table = new Identifier[TXMAX];
	/** Index ukazujici na nasleduji volny prvek */
	private int TableIndex = 0;

	/** Vyhleda symbol v tabulce symbolu
	  * @param id jmeno symbolu,
	  * @return -1: symbol nenalezen, >=0 : adresa symbolu.
      */
	public int position(String id) {
		int i;
		Table[0].Name = new String(id);
	  	i=TableIndex;
		while (Table[i].Name.compareTo(id) != 0)
			i--;
	  	return i;
	}

	/** Vlozeni konstanty do tabulky symbolu.
      * @param identifier identifikator konstanty,
	  * @param value hodnota konstanty,
	  */
	void enterConstant(String identifier, int value) {
		TableIndex++;
		Table[TableIndex] = new Constant(identifier, value);
	}
	/** Vlozeni promenne do tabulky symbolu.
	  * @param identifier identifikator promenne,
	  * @param address adresa,
	  * @param level uroven zanoreni promenne.
	  */
	void enterVariable(String identifier, int address, int level) {
		TableIndex++;
		Table[TableIndex] = new Variable(identifier, address, level);
	}
	/** Vlozeni procedury do tabulky symbolu 
	  * @param identifier identifikator procedury,
	  * @param level uroven zanoreni procedury,
	  */
	void enterProcedure(String identifier, int level) {
		TableIndex++;
		Table[TableIndex] = new Procedure(identifier, level);
	}
	
	/** Nastaveni adresy symbolu.
	  * @param tx offset symbolu v tabulce,
	  * @param cx nova hodnota adresy.
	  */
	void setAddr(int tx, int cx) {
		if (Table[tx] == null) 
		{
			Table[tx] = new Variable("", cx,0);
		}
		else
		  if (Table[tx] instanceof Locatable)
				((Locatable)Table[tx]).setAddress(cx);
	}
	
	/** Ziskani prislusneho identifikatoru z tabulky identifikatoru 
 	  * @param i offset symbolu.
	  * @return vraceny symbol.
	  */
	Identifier getIdentifier(int i) {
		return Table[i];
	}

	/** Vraci index mista, kde je ulozen posledni vlozeny identifikator.
	  * @return index posledniho identifikatoru.
	  */
	public int getTableIndex() {
		return TableIndex;
	}

    /** Metoda pro vypis kon.tvaru tabulky symbolu do souboru; generuje 
	  * vyjimku IOException.
	  * @param path soubor, kam ma byt vypis tabulky symbolu ulozen.
 	  */
	public void list(String path) throws IOException {

 		int i;
 		try {
 		  	FileWriter file = new FileWriter(path);
 			BufferedWriter out = new BufferedWriter(file);

 			out.write("\n\nTabulka symbolu:");
			out.newLine();
			out.write("***************");
			out.newLine();
 			for (i=1; i<= TableIndex;i++) {
  				out.write(i + " ");
	  			out.write(Table[i].toString());
				out.newLine();
 			}
			out.close();
 		}
 		catch (IOException ee) {
 			System.out.println("File " + path + " couldn't be created.");
 			throw ee;
 		}
		
		
	
		
		
	}
}