// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.expression;

import bdc.util.Fmt;
import bdc.scheme.Environment;
import bdc.scheme.Scheme;
import bdc.scheme.SchemeException;
import bdc.scheme.Stack;
import bdc.scheme.Writer;
import bdc.scheme.compiler.CompileTimeEnvironment;
import bdc.scheme.exception.ArgumentTypeException;
import bdc.scheme.exception.PrimitiveException;

public class Application0 extends Expression
{
    Expression operator;

    public Application0 (Expression operator)
    {
        this.operator = operator;
    }

    public Object eval (Environment environment, Stack stack)
      throws SchemeException
    {
        Object expression = operator.eval(environment, stack);
        if (!(expression instanceof Procedure)) {
            throw new ArgumentTypeException(this,
                                            "Procedure",
                                            expression);
        }

        try {
            return ((Procedure)expression).apply0(stack);
        }
        catch (SchemeException se) {
            backTrace(se);
            return Scheme.NotReached;
        }
        catch (RuntimeException re) {
            throw new PrimitiveException(re);
        }
    }

    /**
        Fixup sub-expressions and return
    */
    public Expression fixupVariables (CompileTimeEnvironment environment)
    {
        operator = operator.fixupVariables(environment);
        return this;
    }

    public String toString ()
    {
        return Fmt.S("(%s)", Writer.write(operator));
    }
}
