// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.procedure;

import bdc.scheme.Pair;
import bdc.scheme.Scheme;
import bdc.scheme.SchemeException;
import bdc.scheme.Stack;
import bdc.scheme.compiler.Compiler;
import bdc.scheme.exception.ArgumentCountException;
import bdc.scheme.expression.Procedure;
import bdc.scheme.expression.ProcedureN;
import bdc.scheme.expression.Quoted;
import java.util.List;
import java.util.ArrayList;

/**
    (apply x y &hellip;)
*/
public class Apply extends ProcedureN
{
    public Object applyN (int n, Stack stack) throws SchemeException
    {
        if (n < 2) {
            throw new ArgumentCountException(this, 2, n);
        }

        Procedure procedure = Scheme.procedure(stack.array[stack.inUse-1],
                                               this);

        List list = new ArrayList();
        for (int i = 2; i < n; i++) {
            list.add(stack.array[stack.inUse-i]);
        }

        Object object = stack.array[stack.inUse-n];
        while (object != Scheme.Null) {
            Pair pair = Scheme.pair(object, this);
            list.add(pair.car);
            object = pair.cdr;
        }
        return Compiler.makeApplication(new Quoted(procedure),
                                        list.toArray()).eval(
                                            null, stack);
    }
}
