/**
 * SymbolTable and SymbolTable entry
 * 
 * @author Antonio Cruz adc2104@columbia.edu
 * @version $Id: SymbolTable.java,v 1.13 2007/12/16 07:32:41 admin Exp $
 */

import java.util.*;


public class SymbolTable {
	HashMap table;

	SymbolTable outer;

	public SymbolTable(SymbolTable st) {
		table = new HashMap();
		outer = st;
	}
	
	class SymTabEntry { 
		SymTabEntry(String t, String y, String v) {
			token=t; type=y; value=v;
		}
		// type here is AS type, e.g. Sprite, Number, TextField
		String token, type, value;
		boolean declared;
		public String toString() {
			return token + "," + type + "," + value + "," + declared;
		}
	}

	public void put(String token, String type, String value) {
		if (!alreadyDeclared(token) && table.get(token) == null) {
			table.put(token, new SymTabEntry(token, type, value));
		}
	}

	public SymbolTable.SymTabEntry get(String token) {
		for (SymbolTable table = this; table != null; table = table.outer) {
			SymbolTable.SymTabEntry entry = (SymbolTable.SymTabEntry) (table.table.get(token));
			if (entry != null)
				return entry;
		}
		return null;
	}
	
	public boolean alreadyDeclared(String token) {
		boolean declared = false;
		int depth = 0;
		for (SymbolTable table = this; table != null; table = table.outer) {
			SymbolTable.SymTabEntry entry = (SymbolTable.SymTabEntry) (table.table.get(token));
			declared = entry != null && depth > 0;
			depth++;
		}
		return declared;
	}
	
	public String toString() {
		
		StringBuffer sb = new StringBuffer();
		String tabs = "";
		for (SymbolTable st = this; st != null; st = st.outer) {
			sb.append(tabs).append("SymbolTable: \n");
			Set entries = st.table.entrySet(); 
			for (Iterator itr = entries.iterator(); itr.hasNext(); ) {
				Map.Entry entry = (Map.Entry) itr.next();
				sb.append(tabs)
					.append(entry.getKey()).append(": ")
					.append(entry.getValue().toString())
					.append('\n');
			}
			tabs += "\t";
		}
		return sb.toString();
	}
	
	
}
