package de.renew.expression;

import de.renew.unify.IStateRecorder;
import de.renew.unify.Tuple;


/**
 * A {@code TupleExpression} is an {@code AggregateExpression} that creates a tuple containing the results of its
 * subexpressions upon evaluation.
 *
 * @author Olaf Kummer
 */
public class TupleExpression extends AggregateExpression {

    /**
     * Constructs a new {@code TupleExpression} from its subexpressions.
     *
     * @param expressions a tuple that holds the expressions that must be evaluated
     */
    public TupleExpression(Expression[] expressions) {
        super(expressions);
    }

    /**
     * Constructs a new tuple expression from exactly one
     * expression. Unary tuples are not used very often,
     * but they do occur sometimes.
     *
     * @param expr1 the first expression
     */
    public TupleExpression(Expression expr1) {
        this(new Expression[] { expr1 });
    }

    /**
     * Constructs a new tuple expression from exactly two
     * expressions. Because pairs are so common, it seems
     * desirable to have a short notation for them.
     *
     * @param expr1 the first expression
     * @param expr2 the second expression
     */
    public TupleExpression(Expression expr1, Expression expr2) {
        this(new Expression[] { expr1, expr2 });
    }

    /**
     * Constructs a new tuple expression from exactly three
     * expressions. Because triples are still fairly common, it seems
     * desirable to have a short notation for them.
     *
     * @param expr1 the first expression
     * @param expr2 the second expression
     * @param expr3 the third expression
     */
    public TupleExpression(Expression expr1, Expression expr2, Expression expr3) {
        this(new Expression[] { expr1, expr2, expr3 });
    }

    /**
     * The result of a {@code TupleExpression} is always a tuple.
     *
     * @return {code de.renew.unify.Tuple.class}
     */
    @Override
    public Class<?> getType() {
        return de.renew.unify.Tuple.class;
    }

    /**
     * Creates a {@link Tuple} aggregate using the results of the subexpressions of this {@code TupleExpression}
     * as arguments.
     *
     * @param args the objects to be referenced by the constructed tuple
     * @param recorder a state recorder
     * @return the constructed tuple, possibly incomplete
     */
    @Override
    protected Object makeResultAggregate(Object[] args, IStateRecorder recorder) {
        return new Tuple(args, recorder);
    }
}