// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.expression;

import bdc.scheme.Environment;
import bdc.scheme.GlobalEnvironment;
import bdc.scheme.Scheme;
import bdc.scheme.SchemeException;
import bdc.scheme.Stack;
import bdc.scheme.Writer;
import bdc.scheme.compiler.CompileTimeEnvironment;
import bdc.util.Fmt;

public class Definition extends Expression
{
    GlobalVariable   globalVariable;
    Expression       expression;

    public Definition (GlobalVariable globalVariable,
                       Expression     expression)
    {
        this.globalVariable = globalVariable;
        this.expression     = expression;
    }

    public Object eval (Environment environment, Stack stack)
      throws SchemeException
    {
        try {
            Object object = expression.eval(environment, stack);
            globalVariable.object = object;
            globalVariable.type = GlobalEnvironment.Location;

                // Help provide more sensible error reporting
            if (object instanceof Procedure) {
                ((Procedure)object).name = globalVariable.name;
            }

            return Scheme.Unspecified;
        }
        catch (SchemeException se) {
            backTrace(se);
            return Scheme.NotReached;
        }
    }

    /**
        Fixup sub-expressions and return

        Don't need to fixup GlobalVariable because it can't change
    */
    public Expression fixupVariables (CompileTimeEnvironment environment)
    {
        expression = expression.fixupVariables(environment);
        return this;
    }

    public String toString ()
    {
        return
            Fmt.S("(define %s %s)", globalVariable.name,
                  Writer.write(expression));
    }
}

