// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme;

import bdc.util.GrowOnlyHashtable;

/**
    Symbol represents scheme interned reader symbols
*/
public final class Symbol
{
    /**
        The symbol table itself
    */
    private static final GrowOnlyHashtable SYMBOL_TABLE = new GrowOnlyHashtable();

    /**
        The name of a symbol
    */
    private String name;

    /**
        private constructor
        public interface via New below
    */
    private Symbol (String name)
    {
        this.name = name;
    }

    /**
        Return the symbol for name. Creates a new one if necessary.
    */
    public static Symbol get (String name)
    {
            // check GrowOnlyHashtable without synchronization
        Symbol symbol = (Symbol)SYMBOL_TABLE.get(name);
        if (symbol != null) {
            return symbol;
        }
            // recheck with synchronization to guarantee pointer
            // equality of symbols. All this makes us faster in the
            // common case which is we are looking up an existing
            // symbol.
        synchronized (SYMBOL_TABLE) {
            symbol = (Symbol)SYMBOL_TABLE.get(name);
            if (symbol != null) {
                return symbol;
            }
            symbol = new Symbol(name);
            SYMBOL_TABLE.put(name, symbol);
        }
        return symbol;
    }

    /**
        a symbol simply prints as its name
    */
    public String toString ()
    {
        return name;
    }
}
