package code.lang;

import code.term.*;
import code.instr.*;
import code.modules.CurryModule;
// import code.table.ModuleTable;
import code.type.*;
import code.symbols.*;
import code.space.*;
// import code.stuff.*;
// import code.subst.*;
import static code.type.PredefinedTypes.*;
import static code.type.TypeFactory.*;

import java.util.Vector;
// import java.lang.ref.SoftReference;

/**
 * This class implements the findall and findnext operations.
 *
 * @author Khai Pham
 */

public class FindallModule extends CurryModule {
    public static final String moduleName = "$Findall";
    
    public FindallModule() {
        super(moduleName, new Vector(), null, 0, createSymbols(), false);
    }

    /***********************************************************************
     *                            Findall                                  *
     ***********************************************************************/
    
    /**
     * This instruction initiates a findall search operation. The operation
     * works as follows: The current term's argument, of type (a->Success),
     * is bound to a variable. A client is created to capture the results
     * of the computation and return instantiations of the bound variable
     * one at a time, with successive results encoded in findNext terms.
     */
    
    public static final String findallName = "findall";
    
    // (a->Success)->[a]
    private final static TypeExpression findallType
        = makeFunctionType(
                makeFunctionType(
                        makeTypeVariable("a"),
                        successType),
                makeApplicationType(
                        listTypeName, makeTypeVariable("a")));

    private static final Instruction[] findallCode
        = new Instruction[]{
                new Load((byte) 0),
                FindallInstruction.singleton,
                Replace.singleton
            };

    private static OperationSymbol findallOperation
        = new OperationSymbol(
                moduleName,
                findallName,
                DataSymbol.toplevel,
                1,
                DataSymbol.NonInfix,
                DataSymbol.NonInfix,
                Symbol.Public,
                findallType,
                findallCode);

    public static class FindallInstruction implements Instruction {

        public final static FindallInstruction singleton
	    = new FindallInstruction();

	/**
	 * Executes a findall operation. This code marks the
	 * variables occurring in a term, constructs a findall
	 * client to receive computed search results and updates
	 * the current term with a findNext term, which returns
	 * the first search result.
	 *
	 * @param computation - the initial computation containing the term
	 *                      to conduct a search.
	 */
	public void execute(Computation computation) {
	    throw new RuntimeException
		("Findall not implemented in this branch");
	}
        public String printAsTxtLoadable() {
	    return "external function \"findall\"";
	}
    }
    
    private static Vector createSymbols() {
        Vector v = new Vector();
        v.add(findallOperation);
        return v;
    }
}
