// Mike Maxim
// Imperative Symbol Table

package edu.cmu.cs.l3.symbol;

import java.util.*;

public class SymbolTable {

    public SymbolTable() {
    }

    public void put(Symbol symbol, Object value) throws SymbolTableException {

        if (m_imdtable.get(symbol) != null) {
            throw new SymbolTableException("redefined symbol: " + symbol,value);
        }

        m_imdtable.put(symbol,value);
        m_table.put(symbol,value);
    }

    public Object get(Symbol symbol) {
        return m_table.get(symbol);
    }

    public void remove(Symbol symbol, boolean fromAll) {
        if (fromAll) {
            m_table.remove(symbol);
        }
        m_imdtable.remove(symbol);
    }

    public void beginScope() {
        m_scopes.push(m_table.clone());
        m_imdscopes.push(m_imdtable.clone());

        m_imdtable.clear();
    }

    public void endScope() {
        m_table = (Hashtable) m_scopes.pop();
        m_imdtable = (Hashtable) m_imdscopes.pop();
    }

    public String toString() {
        return m_table.toString() + "\n" + m_imdtable.toString();
    }

    private Hashtable m_table = new Hashtable();
    private Hashtable m_imdtable = new Hashtable();
    private Stack m_scopes = new Stack();
    private Stack m_imdscopes = new Stack();

}