// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.expression;

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.util.Fmt;

public class If extends Expression
{
    Expression predicate;
    Expression consequent;
    Expression alternative;

    public If (Expression predicate,
               Expression consequent,
               Expression alternative)
    {
        this.predicate   = predicate;
        this.consequent  = consequent;
        this.alternative = alternative;
    }

    public Object eval (Environment environment, Stack stack)
      throws SchemeException
    {
        try {
            if (predicate.eval(environment, stack) != Boolean.FALSE) {
                return consequent.eval(environment, stack);
            }
            return alternative.eval(environment, stack);
        }
        catch (SchemeException se) {
            backTrace(se);
            return Scheme.NotReached;
        }
    }

    /**
        Fixup sub-expressions and return
    */
    public Expression fixupVariables (CompileTimeEnvironment environment)
    {
        predicate   = predicate.fixupVariables(environment);
        consequent  = consequent.fixupVariables(environment);
        alternative = alternative.fixupVariables(environment);
        return this;
    }

    public String toString ()
    {
        return Fmt.S("(if %s %s %s)",
                     Writer.write(predicate),
                     Writer.write(consequent),
                     Writer.write(alternative));
    }
}

