// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.procedure;

import bdc.scheme.Scheme;
import bdc.scheme.Stack;
import bdc.scheme.Symbol;
import bdc.scheme.exception.ArgumentTypeException;
import bdc.scheme.expression.Procedure0;
import bdc.util.Fmt;

/**
    Generate a new unique Symbol
*/
public class GenSym extends Procedure0
{
    /**
        current unique id
    */
    private long count = 0;

    /**
        simple interface if the user doesn't care what the symbol looks like
    */
    public Object apply0 (Stack stack) throws ArgumentTypeException
    {
        try {
            stack.addElement("gensym");
            return apply1(stack);
        }
        finally {
            stack.inUse -= 1;
        }
    }

    /**
        This version allows the user to specify a string prefix.
        This greately aids the debugging of macros.
    */
    public Object apply1 (Stack stack) throws ArgumentTypeException
    {
        Object o1 = stack.array[stack.inUse-1];
        /*
            Prefixing with "---" prevnts collisions with the reader. The
            reader does not allow any symbol but "---" itself to start
            with "---".

            We don't just start with a "-" or a "--" because some of
            the builtin rewritters use symbols of that form.
        */
        return Symbol.get(Fmt.S("---%s%s",
                                Scheme.string(o1, this),
                                Long.toString(count++)));
    }
}
